################ 
#####  Notes:
################ 
### Source ---------->  Input ---------->  Model ---------->  Policy Estimates (output)
###  (_so)              (_in)              (_mo)                (_pe)
### values            functions          functions              values
###                   & values           & values             
# - call_sources_f- tax_elasticity_in_f  - tax_revenue_mo_f     - ten_year_revenue_pe
# - policy_f      - est_billionares_in_f - total_rev_mo_f       - ten_year_top_tax_pe
#                                        - ten_years_mo_f       - total_rev_pe
### arguments in functions should used "_var" and functions should "_f"


# DESCRIBE FUNCTIONS STRUCTURE
# - inputs: list
# - outputs: list
#### function:  
#sample_function_f <- function(){
########################################## 
##########################################  
#
#    ...
#
########################################## 
##########################################  
#    return( )                                  # A list with all (most?) the elements 
#}                                              # generated inside the function 
#invisible( list2env(sample_function_f(),.GlobalEnv) ) 
#
# - inputs: none
# - outputs: all the original source values
call_sources_f <- function(){
############################################################################### 
###############################################################################   

    ################  
    ####### Research:
    ################  
    research_so <- read_csv("rawdata/edits/research.csv")      #load data set that contains parameters from research
    # Elasticities
    ela1_so <- as.numeric(research_so[1,"param"])           # 0.5 - David. 2017
    ela2_so <- as.numeric(research_so[2,"param"])           # 0.5 - Jakobsen et al. 2018
    ela3_1_so <- as.numeric(research_so[3,"param"])         # 2   - Londono-Velez 2018
    ela3_2_so <-   as.numeric(research_so[4,"param"])       # 3   - Londono-Velez 2018
    ela4_1_so <- as.numeric(research_so[5,"param"])         # 23  - Brülhart et al. 2016
    ela4_2_so <- as.numeric(research_so[6,"param"])         # 34  - Brülhart et al. 2016
    
    ################
    ###### Data:
    ################ 
    df_forbes_so <- read_dta("rawdata/forbes_20112018_bdays.dta")  # Forbes
    df_scf_so <- read_dta("rawdata/rscfp2016.dta")                 # SCF
    df_dina1_so <- read_dta("analysis_data/dina.dta")              # DINA
    # The source data file for DINA is confidential. Instructions 
    # to obtain it are in code chunk of section #3.               

    # Total wealth and number of households [SOURCE NEEDED]
    total_hhlds_so <- 129.4e6  # [SOURCE]
    # Macroeconomy/demographics
    inflation_so <- 0.025      # CBO/JCT
    population_gr_so <- 0.01   # CBO/JCT 
    real_growth_so <- 0.02     # CBO/JCT
    hhld_gr_so <- 0.009        # [SOURCE]
    
    ################ 
    #####  Guesswork:
    ################ 
    

############################################################################### 
############################################################################### 
    return( sapply( ls(pattern= "_so\\b"), function(x) get(x) ) ) 
}
invisible( list2env(call_sources_f(),.GlobalEnv) )

Tax revenue from wealth tax in first year: $199 billion Tax revenue from wealth tax over 10 year: $2.6 trillion

Percentage of US households paying the wealth tax: 0.05%

Click here to explore different policy proposals and to see how the assumptions of the analysis affect the results.

There are two ways to edit the code behind this document:
1 - Download/Clone this repository into your computer. You will need to install R and RStudio.

2 - Go to this link and reproduce all the results in a computing enviroment (supported by project binder). You will not need to install anything in your computer.

Executive Summary

INSERT EXEC SUMMARY HERE

*

Open Policy Analysis

INSERT OPA THING HERE

1 Policy choices

The wealth tax applies to net worth (sum of all assets net of debts) above $50 million, and obeys the following structure:

# - inputs: none 
# - outputs: all the original source values
#### Policy:  
policy_f <- function(){
############################################################################### 
###############################################################################  
  
    # brackets_po
    brackets_po <- c(10, 25, 50, 100, 250, 500,  1000) * 1e6
    tax_rates_po <- c(  0,    0, 0.02,  0.02,  0.02,  0.02, 0.03) 
    starting_brack_po <- brackets_po[min(which(tax_rates_po>0))]
    next_increase_po <- brackets_po[min(which(tax_rates_po>0.02))]
    main_tax_po <- median(tax_rates_po)
    max_tax_po <- max(tax_rates_po)
    
############################################################################### 
###############################################################################  
    return( sapply( ls(pattern= "_po\\b"), function(x) get(x)) ) 
}
invisible( list2env(policy_f(),.GlobalEnv) )

knitr::kable(cbind("Bracket (millions of $)" = brackets_po/1e6,
                   "Marginal Tax Rate (%)" = 100*tax_rates_po) )%>%
  kable_styling()  
Bracket (millions of $) Marginal Tax Rate (%)
10 0
25 0
50 2
100 2
250 2
500 2
1000 3

Household net worth above $5 million would be taxed at 2%. Any wealth over $1 billion would be taxed an additional 1% (a billionaire surtax).

2 Compute tax avoidance elasticity

To calculate the revenue from this wealth tax, the extent of wealth tax evasion/avoidance is estimated based on recent research showing that it depends crucially on loopholes and enforcement. The tax-avoidance elasticity is computed as the average elasticity from four studies. The table lists the four studies and the avoidance/evasion response to a 1% wealth tax.

Authors Year paper Publisher Avoidance/evasion response
Seim, David 2017 “Behavioral Responses to an Annual Wealth Tax: Evidence from Sweden” American Economic Journal: Economic Policy, 9(4), 395-421 0.5
Jakobsen, Kristian, Katrine Jakobsen, Henrik Kleven and Gabriel Zucman. 2018 “Wealth Accumulation and Wealth Taxation: Theory and Evidence from Denmark” NBER working paper No. 24371 0.5
Londono-Velez, Juliana and Javier Avila. 2018 “Can Wealth Taxation Work in Developing Countries? Quasi-Experimental Evidence from Colombia” UC Berkeley working paper 2-3
Brülhart, Marius, Jonathan Gruber, Matthias Krapf, and Kurt Schmidheiny. 2016 “Taxing Wealth: Evidence from Switzerland” NBER working paper No. 22376, 2016 23-34

Seim (2017) and Jakobsen et al. (2018) obtain small avoidance/evasion responses in the case of Sweden and Denmark, two countries with systematic third party reporting of wealth: a 1% wealth tax reduces reported wealth by less than 1%. Londono-Velez and Avila (2018) show medium avoidance/evasion responses in the case of Colombia where enforcement is not as strong: a 1% wealth tax reduces reported wealth by about 2-3%. The study on Switzerland by Brülhart et al. (2016) is an outlier that finds very large responses to wealth taxation in Switzerland: a 1% wealth tax lowers reported wealth by 23-34%. This extremely large estimate is extrapolated from very small variations in wealth tax rates over time and across Swiss cantons and hence is not as compellingly identified as the other estimates based on large variations in the wealth tax rate. Switzerland has no systematic third party reporting of assets which can also make tax evasion responses larger than in Scandinavia.

# input: elasticity parameters from research, main tax, adjutment factor
# ouptut: final elasticity (final_ela_in), evasion parameter (evasion_param_in)  
tax_elasticity_in_f <- function(ela1_var = ela1_so, ela2_var = ela2_so, 
                                ela3_1_var = ela3_1_so, ela3_2_var = ela3_2_so, 
                                ela4_1_var = ela4_1_so, ela4_2_var = ela4_2_so,
                                main_tax_var = main_tax_po){
############################################################################### 
###############################################################################  
  
    final_ela_in <- mean(c(ela1_var, ela2_var, (ela3_1_var + ela3_2_var)/2, 
                           (ela4_1_var + ela4_2_var)/2))
    evasion_param_in <- main_tax_var * final_ela_in
    
############################################################################### 
###############################################################################  
    return(list("final_ela_in" = final_ela_in, 
                "evasion_param_in" = evasion_param_in))
}
invisible( list2env(tax_elasticity_in_f(),.GlobalEnv) ) 

The final 16% tax avoidance/evasion response to a 2% wealth tax was computed as and average across these four studies (2%*(0.5+0.5+2.5+28.5)/4).

3 Data sources

Three data sources were used in this analysis:

3.1 Data cleaning

From each data set three variable were extracted: networth that contain information on wealth, weights represents the number of households that each observation represents and data which tracks the data of origin.

The following transformations were applied to the data:

  • Each observation in DINA is aggregated into groups of 5 observations to anonymize the data.
  • SCF was aged by inflating the number of households and wealth uniformly to match the most recent aggregate projections for population and total household wealth from the Federal Reserve Board. After that, SCF wealth was scaled to match the total of DINA minus the wealth of Forbes (to prevent double counting of wealth).
  • After combining (appending) all three data sources, the population weights of SCF and DINA where combined by the taking the average of the two.
##### Reproducing do file ('wealthtax.do')
# inputs: 
# outputs: df_forbes1_in, df_dina1_in, df_scf1_in, df_in, total_wealth_scf_in,
# total_wealth_in
clean_data_f <- function(df_forbes_var = df_forbes_so, df_dina1_var = df_dina1_so,
                         df_scf_var = df_scf_so){
############################################################################### 
###############################################################################

    ### Forbes data 
    df_forbes1_in <- df_forbes_var  %>%                     
      filter(forbes_yr == 2018) %>% 
      mutate("networth" = net_worthmillions * 1e6, 
               "weight" = 1, 
               "data" = "FB400") %>%
      select(data, networth, weight) %>% 
      filter( !is.na(networth) )
    forbesmin <- min(df_forbes1_in$networth)
    f400tot <- sum(df_forbes1_in$networth * df_forbes1_in$weight) / 1e12  
    #cat("TOTAL FORBES NETWORTH 2018 (Tr) = ", f400tot,  "FORBES MIN WEALTH 2018 = ", forbesmin)
    
    ### DINA data 
    ####### This section uses data that cannot be shared for confidentiality reasons
    ####### Below is the code used to aggregate the data.
    ####### If you have access to the orginal data set, set is_dina_public_so = TRUE.
    ####### To obtain this data please contact Gabriel Zucman at zucman@gmail.com
    ####### The file that you will obtain should have the following signature:
    ####### in R: digest("usdina2019.dta", file = TRUE) produces: 
    ####### "2f5d529b1e89e39171927dc28bfebbe4"
    ####### in Stata, datasignature produces: 
    ####### "282866:4(49628):4083279708:1806586907"
    
    # With access to
    # private DINA, set indicator to below to TRUE
    is_dina_public <- FALSE                        
    if(is_dina_public){
      # paste below the path to where usdina2019.dta is in your computer
      path_to_dina <- paste0("HERE_GOES_YOUR_PATH", "/usdina2019.dta")
      df_dina_so <- read_dta(path_to_dina)
      df_dina <- df_dina_so %>% 
      group_by(id) %>% 
      summarise("networth" = round(sum(hweal)),  # rounding of networth is to make it compatible with Stata
                "weight" = mean(dweght)/1e5) 
        
      totw_dina <- sum(df_dina$networth * df_dina$weight) / 1e12
      #cat("TOTAL DINA NETWORTH 2019  (Tr) ", totw_dina)
      
      totn_dina <- sum(df_dina$weight)
      
      df_dina$data <- "DINA"
      
      # Aggregate into bins of 5 househodls info to protect confidentiality
      df_dina1 <- df_dina %>% 
        mutate("aux_id" = 1:dim(df_dina)[1]) %>% 
        arrange(desc(networth),aux_id) %>% 
        # Still not clear what the role of the "+3" is.  
        mutate("group" = floor((1:dim(df_dina)[1] + 3) / 5)) %>% 
        group_by(group) %>% 
        summarise("weight" = sum(weight),
                  "networth" = mean(networth)) %>% 
        mutate("data" = "DINA") %>% 
        select("data", "networth", "weight")
      write_dta("analysis_data/dina.dta", data = df_dina1)
      df_dina1_in <- read_dta("analysis_data/dina.dta")
    } else {
      df_dina1_in <- df_dina1_var 
    }
    #### End of confidential section
    totw_dina <- sum(df_dina1_in$networth * df_dina1_in$weight) / 1e12
    ### SCF data 
    
    # Increase the population weigths to reflect population growth from 2016 to 1019
    df_scf_var <- df_scf_var %>% 
          mutate("wgt2019" = round( wgt * (1 + hhld_gr_so)^( 2019 - 2016 )))
    totw <- sum(df_scf_var$networth * df_scf_var$wgt2019) / 1e12
    totn <- sum(df_scf_var$wgt2019)
    totw_scf <- sum(df_scf_var$networth * df_scf_var$wgt) / 1e12
    #cat("TOTAL SCF NETWORTH 2016  (Tr)", totw_scf)
    
    # Rescaling SCF to match total total wealth reported in DINA excluding the f400
    df_scf1_in <- df_scf_var %>% mutate("networth" = networth * ( totw_dina - f400tot ) / totw, 
                                "weight" = wgt2019, 
                                "data" = "SCF") %>%
      select(data, networth, weight)
    
    # Combine three data sources
    df <- rbind(df_forbes1_in, df_scf1_in, df_dina1_in)
    
    # If observation is in SCF or DINA, then divide their weights in 2
    df$weight <- with(df, ifelse(data=="SCF" | data=="DINA", 
                                   round(weight/2), weight) )
    # All obs from SCF and DINA that have wealth above the min of forbes are droped to avoid duplications
    df_in <- df %>% filter( !(networth > forbesmin & ( data == "SCF" | data == "DINA" ) ) )
    
    # df %>% 
    #   summarise( mean(networth), sd(networth) ) 
    
    total_wealth <- df_in %>% 
      summarise(sum(networth * weight) / 1e12) %>% 
      as.numeric()
    fifty_millio_wealth <- df_in %>% 
      filter(networth >= 50e6) %>% 
      summarise(sum(networth * weight) / 1e12) %>% 
      as.numeric()
    
    #cat("Total wealth (in trillions) is ", total_wealth, ". Wealth for billionares total wealth is ", fifty_millio_wealth) 
    
    write_dta("analysis_data/wealth.dta", data = df_in, version = 11)
    
    # Very small differences with stata output (but it should be zero differences)
    # wealth <- read_dta("~/Downloads/wealthtaxsim/data/wealth.dta")
    # diff_aux <- abs( df_in$networth -  wealth$networth )
    # summary(abs(diff_aux))
    #     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
    #    0.000    0.000    0.008    0.928    0.174 3328.000 
    
    total_wealth_scf_in <- df_scf_var %>% 
      summarise(sum(networth * wgt)/1e12) %>%  
      as.numeric()
    total_wealth_in <- df_in %>%  
      summarise(sum(networth * weight)/1e12) %>%  
      as.numeric()
    
###############################################################################
###############################################################################  
     return(list("df_forbes1_in" = df_forbes1_in, "df_dina1_in" = df_dina1_in, 
     "df_scf1_in" = df_scf1_in, "df_in" = df_in, "total_wealth_scf_in" = total_wealth_scf_in, 
     "total_wealth_in" = total_wealth_in))
}
invisible(list2env(clean_data_f(),.GlobalEnv) ) 

The total household net worth projection is $94 trillion for 2019 (the SCF records a total household net worth of $87 trillion in 2016).

3.2 Generating percentiles and micro-percentiles

In this section, the microdata generated before (wealth.dta) is aggregated into percentiles and fractions of a percentile. The final analytic file contains: percentile or fraction of percentile (gperc), number of households in that group (nb), lowest level of wealth in that group (thres), and average level of wealth in that group (avg)

*# The code below does not run as part of the dynamic document and is presented only
*# for reproducibility purposes.
*# To run the code below you will require a license of Stata 11 or higher. You will also need to 
*# place a copy of the file 'gperc.ado', located in the 'rawdata' folder of this repository 
*# into your ado folder.   
*# paste the directory of the repository in your computer below: 
global  repository   "YOUR PATH HERE"

sysdir set PERSONAL "$repository/rawdata/"

* creating an excel table for the simulation
use $repository/analysis_data/wealth.dta, clear
cap gen aux_id = _n
sort aux_id
gperc networth [w=weight], matname(wealthperc)  
mat list wealthperc 
clear
svmat wealthperc, names(col)
qui compress
export delimited using "$repository/analysis_data/tax_grid.csv", replace

4 Number of affected households and their total tax base

To compute the relevant universe the evasion parameter of 16% is applied to both the threshold and the average wealth of each percentile (and fraction of a percentile)

# DESCRIBE FUNCTIONS STRUCTURE
# - inputs: list
# - outputs: list
#### function:  
#sample_function_f <- function(){
################################################################################ 
################################################################################  
#
#    ...
#
################################################################################ 
################################################################################  
#    return( )                                 
#}                                             
#invisible( list2env(sample_function_f(),.GlobalEnv) )

grid <- read.csv("analysis_data/tax_grid.csv")  %>% 
  filter(!is.na(gperc))

# Wealth per bin (percentile) after evasion  
grid$thresNew <- (1 - evasion_param_in) * grid$thres
grid$avgNew <- (1 - evasion_param_in) * grid$avg 

##### Num hhlds:
#no avoidance
target_hhlds_noav_mo <- grid %>% 
  filter(thres > starting_brack_po) %>% 
  summarise(sum(nb))

#with avoidance
target_hhlds_mo <- grid %>% 
  filter(thresNew > starting_brack_po) %>% 
  summarise(sum(nb))

### Billionares:
#no avoidance
target_hhlds_bn_noav_mo <- grid %>% 
  filter(thres > next_increase_po) %>% 
  summarise(sum(nb))

#with avoidance
target_hhlds_bn_mo <- grid %>% 
  filter(thresNew > next_increase_po) %>% 
  summarise(sum(nb))

##### Total Taxable Wealth:
tax_base_total_noav_mo <- grid %>% 
  filter(thres > starting_brack_po) %>% 
  summarise(sum((avg - starting_brack_po) * nb)/1e12)

#with avoidance
#2% above 50m
tax_base_total_mo <- grid %>% 
  filter(thresNew > starting_brack_po) %>% 
  summarise(sum((avgNew - starting_brack_po) * nb)/1e12)

#billionares additional 1%
tax_base_total_surtax_noav_mo <- grid %>% 
  filter(thres > next_increase_po) %>% 
  summarise(sum((avg - next_increase_po) * nb)/1e12)
tax_base_total_surtax_mo <- grid %>% 
  filter(thresNew > next_increase_po) %>% 
  summarise(sum((avgNew - next_increase_po) * nb)/1e12)

# rounding number to display in the next paragraphs
target_hhlds_noav_round <- format(round(target_hhlds_noav_mo / 1000) * 1000 , scientific = FALSE)
target_hhlds_round <- format(round(target_hhlds_mo / 1000) * 1000, scientific = FALSE)
target_hhlds_bn_noav_round <- round(target_hhlds_bn_noav_mo / 1000) * 1000 
target_hhlds_bn_round <- round(target_hhlds_bn_mo / 1000) * 1000 

In 2019, there would be around 63000 households liable for the wealth tax (78000 before accounting for avoidance). This would be less than 0.05% of the 130 million US households in 2019.

4.1 2% tax on all wealth above $50 millions

The 62598 households with assests totaling over $50 million would have a total taxable wealth (above the $50million) of $8.9 trillion, i.e. approximately 9% of the $94 trillion population-wide, total household net worth.

4.2 1% additional tax on all wealth above $1 billion

The 961 households with assests totaling over $1 billion dollars would have a total taxable wealth (above the $1billion) of $2.2 trillion, i.e. approximately 2% of the $94 trillion population-wide, total household net worth.

5 Total tax revenue in one year

# DESCRIBE FUNCTIONS STRUCTURE
# - inputs: list
# - outputs: list
#### function:  
#sample_function_f <- function(){
################################################################################ 
################################################################################  
#
#    ...
#
################################################################################ 
################################################################################  
#    return( )                                 
#}                                             
#invisible( list2env(sample_function_f(),.GlobalEnv) )



 
# Total tax collected in a year
# amount from 2%
# amount from extra 1%

#This function computes the total tax collected for a tax unit with wealth "wealth_var", applying "taxrates_var" to "brackets_var"
# - inputs: wealth, tax rates, brackets to tax
# - ouputs: total tax collected
get_tax_rev <- function(wealth_var = wealth_aux, taxrates_var = tax_rates_po,
                          brackets_var = brackets_po) {
    ## expecting taxLevels in percentage
    # taxLevels <- taxLevels / 100
    if (length(brackets_var) != length(taxrates_var)){
      stop("Tax brackets and tax rates do not match")
    }
   # Compute max taxable wealth per bracket
    max_tax_per_brack <- c(diff(c(0, brackets_var)), 1e100)
   # Substract wealth minus tax bracket. If wealth above a given bracket (difference is larger than max taxable wealth), 
   # then assign max taxable wealth to that given bracket
    to_tax <- ifelse( wealth_var - c(0, brackets_var) > max_tax_per_brack, 
                      max_tax_per_brack, 
                      ( wealth_var - c(0,brackets_var) ) )   
   # If wealth if lower than a given bracket (difference between wealth and bracket is negative), then assign zero to that bracket  
    to_tax <- ifelse( to_tax<0, 0, to_tax )
    # Apply trax rates to each corresponding bracket and all together
    total_tax <- sum( to_tax * c(0, taxrates_var) )   
    return(total_tax)
}

# IMPORTANT: this (similar to getTaxBasePerBracket) was differing from simple
# calculation below because this was not subseting to wealth above 50m.
# computes tax payed by each average wealth per percintile (up to 2%)

## gets taxes paid per group (percentile and micropercentile)
get_tax_rev_per_group <- function(grid_var = grid, taxLevels_var = tax_rates_po, brackets_var1 = brackets_po) {
  grid_var <- grid_var %>% filter(thresNew > starting_brack_po)
  aux_var <- sapply(grid_var$avgNew, 
                   function(x) get_tax_rev(wealth_var = x, 
                                             taxrates_var = taxLevels_var, 
                                             brackets_var = brackets_var1))
  return(sum(grid_var$nb * aux_var) / 1e9)
}

tax_rev_init_mo <- get_tax_rev_per_group(taxLevels = c(tax_rates_po[-7], 0.02))
## Warning in get_tax_rev_per_group(taxLevels = c(tax_rates_po[-7], 0.02)): partial
## argument match of 'taxLevels' to 'taxLevels_var'
top_tax_rev_in <- get_tax_rev_per_group(taxLevels = c(rep(0,6), 0.01))
## Warning in get_tax_rev_per_group(taxLevels = c(rep(0, 6), 0.01)): partial
## argument match of 'taxLevels' to 'taxLevels_var'
total_tax_rev <- get_tax_rev_per_group(taxLevels = tax_rates_po)
## Warning in get_tax_rev_per_group(taxLevels = tax_rates_po): partial argument
## match of 'taxLevels' to 'taxLevels_var'
#199.7889

# The following replicates stata code more closely and seems more straightforward. 
# Howevere it differs more from the code in the app. Consider this in both (app and DD)
# in the future
if (FALSE){
    #with avoidance
    #2% above 50m
    tax_rev_init_mo <- grid %>% 
      filter(thresNew > starting_brack_po) %>% 
      summarise(sum((avgNew - starting_brack_po) * nb * 0.02)/1e9) %>% as.numeric()
    
    #billionares additional 1%
    top_tax_rev_in <- grid %>% 
      filter(thresNew > next_increase_po) %>% 
      summarise(sum((avgNew - next_increase_po) * nb * 0.01)/1e9) %>% as.numeric()
    
    total_tax_rev <- total_tax_base + total_tax_sur_bill
}

# TO DELETE ALL BELOW?
getPeoplePerBracket=function(grid, brackets){
  brackets = c(brackets, 1e12) ## get last bracket
  grid$group=cut(grid$thresNew, brackets)
  toReturn = grid %>% 
    group_by(group) %>% 
    summarise(totalPeople=sum(nb)) %>% 
    drop_na()
  return(toReturn)
}

numberTaxpayers <- getPeoplePerBracket(brackets = brackets_po, grid = grid)
## `summarise()` ungrouping output (override with `.groups` argument)
#Revenue
#From here on: keep
target_hhlds_mo <- sum( numberTaxpayers$totalPeople[brackets_po>=starting_brack_po] )

Starting with the $8.9 trillion tax base of wealth above $50 million ($11.3 with no avoidance), a 2% tax would raise $177 billion in 2019. The billionaire surtax is estimated to apply to a base of $2.2 trillion ($2.8 with no avoidance) from about 1000 billionaire families (1300 with no avoidance). Thus the billionaire surtax would raise $22 billion in 2019. The combination of the 2% tax above $50 million and the billionaire surtax would raise 177.2 + 21.6 = 198.8 billion in 2019.

6 Ten year projections

# - inputs: inflation_so, population_gr_so, real_growth_so, total_rev_pe, top_tax_rev_in
# - ouputs: discount_rate_mo, ten_year_factor_mo, ten_year_revenue_pe, ten_year_top_tax_pe
ten_years_mo_f <- function(inflation_var = inflation_so, population_gr_var = population_gr_so,
                           real_growth_var = real_growth_so, total_rev_var = total_tax_rev, 
                           top_tax_base_var = top_tax_rev_in){
############################################################################### 
###############################################################################
  
    discount_rate_mo <- inflation_var + population_gr_so + real_growth_so  
    ten_year_factor_mo <- sum( ( 1 + discount_rate_mo )^( 0:9 ) ) 

    ten_year_revenue_pe <- total_rev_var * ten_year_factor_mo     
    #ten_year_revenue_pe <- total_rev_pe * ten_year_factor_mo                      #PE
    ten_year_top_tax_pe <- top_tax_base_var * ten_year_factor_mo          
    #ten_year_top_tax_pe <- top_tax_base_var * ten_year_factor_mo                  #PE
    
############################################################################### 
###############################################################################
    return( list("discount_rate_mo" = discount_rate_mo, "ten_year_factor_mo" = ten_year_factor_mo, 
           "ten_year_revenue_pe" = ten_year_revenue_pe, "ten_year_top_tax_pe" = ten_year_top_tax_pe) )
}
invisible( list2env(ten_years_mo_f(),.GlobalEnv) )

To project tax revenues over a 10-year horizon, we assume that nominal taxable wealth would grow at the same pace as the economy, or 5.5% per year as in standard projections of the Congressional Budget Office or the Joint Committee on Taxation. This growth is decomposed into 2.5% price, 1% population growth, and 2% of real growth per capita. This implies that tax revenue over 10 years 2019-2028 is about 12.9 times the revenue raised in 20193. This uniform growth assumption is conservative as the wealth of the rich has grown substantially faster than average in recent decades. The estimates by Saez and Zucman4 show that, from 1980 to 2016, real wealth of the top 0.1% has grown at 5.3% per year on average, which is 2.8 points above the average real wealth growth of 2.5% per year. Average real wealth of the Forbes 400 has grown even faster at 7% per year, 4.5 points above the average. The historical gap in growth rates of top wealth vs. average wealth is larger than the proposed wealth tax. Therefore, even with the wealth tax, it is likely that top wealth would continue to grow at least as fast as the average.

This 10-year projection implies that revenue raised by the progressive wealth tax would be 12.9 * 198.8 = $2560 billion, rounded to $2.6 trillion. Out of this $2.6 trillion, the billionaire surtax would raise 21.6 * 12.9 = $278.7 billion, rounded to $0.3 trillion.

It is important to emphasize that our computations assume that the wealth tax base is comprehensive with no major asset classes exempt from wealth taxation. Introducing exemptions for specific asset classes would reduce the revenue estimates both mechanically and dynamically as wealthy individuals would shift their wealth into tax exempt assets. Because Senator Warren’s proposal does not include any large exemptions, we do not believe our revenue estimate needs to be adjusted.

7 Visualization

The figure below illustrates the distribution of wealth tax across the population:

# Clean up the code (but do not make changes).   
taxRate <- c(mean(tax_rates_po[1:2]), mean(tax_rates_po[3:5]), tax_rates_po[6],
             tax_rates_po[7]) * 100
brackets <- c(min(brackets_po[1:2]), min(brackets_po[3:5]), brackets_po[6], 
              brackets_po[7]) / 1e6
#this section sorts the tax brackets. Not needed outside the app    
if (FALSE){          
    ## reshuffle to make sure brackets are increasing
    ## tax rates not forced to be monotonic
    reorderIdx <- order(as.numeric(brackets))
    brackets <- brackets[reorderIdx]
    taxRate <- taxRate[reorderIdx]
}
  
### KATIE: change the 1e5 to whatever you want to be the minimum
xval <- 10^seq(log10(1e5), log10(max(grid$thresNew)), by = 0.001) ## get uniform on log scale
 #(max(grid$thresNew))
if(FALSE){
    idx0 <- xval <= as.numeric(brackets[1]) * 1e6
    idx1 <- xval <= as.numeric(brackets[2]) * 1e6 & xval > as.numeric(brackets[1]) * 1e6
    idx2 <- xval > as.numeric(brackets[2]) * 1e6 & xval <= as.numeric(brackets[3]) * 1e6
    idx3 <- xval > as.numeric(brackets[3]) * 1e6 & xval <= as.numeric(brackets[4]) * 1e6
    idx4 <- xval > as.numeric(brackets[4]) * 1e6
    idx <- cbind.data.frame(idx0, idx1, idx2, idx3, idx4)
   # Indicator across income on tax bracket position
    getGroup <- unlist(apply(idx, 1, function(x) {
      which(x)[1]
    }))

    toPlot <- cbind.data.frame(xval, getGroup)  
}
    #brackets_po <- c(0, 25, 50, 100, 250, 500, 1000) * 1e6
getGroup <- as.numeric(cut(xval, c(0, brackets * 1e6, 1e12), include.lowest = TRUE))

toPlot <- cbind.data.frame(xval, getGroup)  
#summary(toPlot)
#toMatch <- cbind.data.frame(group = 1:7, tax = tax_rates_po)
toMatch <- cbind.data.frame(group = 1:(length(taxRate) + 1), tax = c(0, taxRate))
 
toPlot2 <- merge(toPlot, toMatch, by.x = "getGroup", by.y = "group")

#lapply(x = 1:5, f(x,y), y = 6:10) = (1, 6:10); (2, 6:10);... ;(5, 6:10)  
toPlot2$averageInt <- sapply( toPlot2$xval, 
                              function(x) get_tax_rev(wealth_var = x, 
                                                        taxrates_var = taxRate/100, 
                                                        brackets_var = brackets * 1e6) )

# Here is where the total tax payed by each individuals is transform into average tax rates
toPlot2$averageRate <- (toPlot2$averageInt / toPlot2$xval) * 100

toPlot2$id <- 1:nrow(toPlot2)
#browser()
if(FALSE) {
    # unaffected by new grouping
    toPlot2$marginalInt <- unlist(lapply(toPlot2$xval, getAverageTax, taxRate, brackets))

    toPlot2$marginalRate <- (toPlot2$marginalInt / toPlot2$xval) * 100

    toPlot2$id <- 1:nrow(toPlot2)
}
#summary(toPlot2)
#end of dataInputT
   
# These are mini data set that ggvis needs to cre ate vertical lines
extra0 <- cbind.data.frame(x = rep(max(as.numeric(brackets[1]) * 1e6, 1e5), 2), y = c(0, taxRate[1]))
extra1 <- cbind.data.frame(x = rep(as.numeric(brackets[2]) * 1e6, 2), y = c(0, taxRate[1]))
extra1b <- cbind.data.frame(x = rep(as.numeric(brackets[2]) * 1e6, 2), y = c(0, taxRate[2]))
extra2 <- cbind.data.frame(x = rep(as.numeric(brackets[3]) * 1e6, 2), y = c(0, taxRate[2]))
extra2b <- cbind.data.frame(x = rep(as.numeric(brackets[3]) * 1e6, 2), y = c(0, taxRate[3]))
extra3 <- cbind.data.frame(x = rep(as.numeric(brackets[4]) * 1e6, 2), y = c(0, taxRate[3]))
extra3b <- cbind.data.frame(x = rep(as.numeric(brackets[4]) * 1e6, 2), y = c(0, taxRate[4]))

showAvg <- function(x) {
  # https://stackoverflow.com/questions/28396900/r-ggvis-html-function-failing-to-add-tooltip/28399656#28399656
  # https://stackoverflow.com/questions/31230124/exclude-line-points-from-showing-info-when-using-add-tooltip-with-hover-in-ggvis
  if (sum(grepl("id", names(x))) == 0) return(NULL)
  if (is.null(x)) return(NULL)
  
  data <- toPlot2

  row <- data[data$id == x$id, ]

  #The following section does not work in the static plot
  if(FALSE){
  paste0("Average Tax Rate: ", round(row$averageRate, 2), "%", 
         " <br> Wealth ($m): ", round(row$xval / 1e6, 0), 
         "<br> Top ", getPercentile(grid, row$xval / 1e6), 
         "%", "<br> Taxes Paid ($m): ", round(row$averageInt / 1e6, 2), 
         sep = "") ## dividing by 1e6 may need to change if we do this for xval overall
  }
}


getPercentileMarkers <- function(grid) {
    c(
      grid$thresNew[which(grid$gperc == 90)],
      grid$thresNew[which(grid$gperc == 99)],
      grid$thresNew[which(grid$gperc >= 99.9 & grid$gperc < 99.99)[1]],
      grid$thresNew[which(grid$gperc >= 99.99 & grid$gperc < 99.999)[1]]
    )
  }

data <- toPlot2

markers <- data.frame(a = c(getPercentileMarkers(grid) / 1e6, 
                           max(grid$thresNew) / 1e6), 
                     b = rep(0.25, 5), 
                     c = c("Top 10%", "Top 1%", "Top 0.1%", "Top 0.01%", "Maximum"))

valuesInt <- c(brackets, round(max(grid$thresNew) / 1e6, 2), 
               round(getPercentileMarkers(grid) / 1e6, 2))
valuesInt <- sort(valuesInt)
rmIdx <- ncol(data)
plot <- data[, -rmIdx] %>%
  ggvis(x = ~ xval / 1e6, y = ~tax) %>%
  layer_points() %>%
  layer_points(data = subset(data, xval / 1e6 <= max(grid$thresNew) / 1e6), 
               x = ~ xval / 1e6, 
               y = ~averageRate, stroke := "red", key := ~id) %>%
  add_tooltip(showAvg, "hover") %>%
  # layer_lines(data = subset(data,xval/1e6<=45000),x = ~ xval / 1e6, y = ~marginalRate, stroke := "red") %>%
  layer_paths(data = extra1, ~ x / 1e6, ~y) %>%
  # layer_paths(data = extra2, ~ x / 1e6, ~y) %>%
  # layer_paths(data = extra3, ~ x / 1e6, ~y) %>%
  layer_paths(data = extra0, ~ x / 1e6, ~y) %>%
  layer_paths(data = extra1b, ~ x / 1e6, ~y) %>%
  # layer_paths(data = extra2b, ~ x / 1e6, ~y) %>%
  # layer_paths(data = extra3b, ~ x / 1e6, ~y) %>%
  layer_text(data = markers, ~a, ~b, text := ~c, align := "center", fontWeight := "bold") %>%
  add_axis("x",
    title_offset = 80, title = "Wealth ($m)", grid = F, format = ",",
    values = valuesInt, properties = 
      axis_props(labels = list(angle = 45, align = "left", baseline = "middle"))
  ) %>%
  add_axis("y", title = "Tax rate (%)") %>%
  scale_numeric("x", trans = "log", expand = 0) %>%
  set_options(width = 800, height = 500) %>%
    layer_paths(data = extra2, ~ x / 1e6, ~y) %>%
    layer_paths(data = extra2b, ~ x / 1e6, ~y) %>%
    layer_paths(data = extra3, ~ x / 1e6, ~y) %>%
    layer_paths(data = extra3b, ~ x / 1e6, ~y)
  plot

Tax revenue from wealth tax in first year: $199 billion

Tax revenue from wealth tax over 10 year: $2.6 trillion

Percentage of US households paying the wealth tax: 0.05%

Click here to explore different policy proposals and to see how the assumptions of the analysis affect the results.

There are two ways to edit the code behind this document:
1 - Download/Clone this repository into your computer. You will need to install R and RStudio.

2 - Go to this link and reproduce all the results in a computing enviroment (supported by project binder). You will not need to install anything in your computer.

8 Wealth inequality

One of the key motivations for introducing a progressive wealth tax is to curb the growing concentration of wealth. The top 0.1% wealth share has increased dramatically from about 7% in the late 1970s to around 20% in recent years. Conversely, the wealth share of the bottom 90% of families has declined from about 35% in the late 1970s to about 25% today. This fall has been primarily the consequence of increased debt for the bottom 90% (through mortgage refinance, consumer credit, and student loans). As a result, the top 0.1% today owns almost as much wealth as the bottom 90% of US families.

9 Tax burden on the wealthiest 0.1%

The estimates of Piketty, Saez, and Zucman (2018) show that the total burden (including all taxes at the federal, state, and local levels) of the wealthiest 0.1% families is projected to be 3.2% of their wealth in 2019 (they have on average $116 million in wealth, and pay total of $3.68 million in taxes). The proposed progressive wealth tax would add an extra $1.27 million (or 1.1% of wealth) to their tax burden for a total tax burden (relative to wealth) of 4.3%.

In contrast, the bottom 99% families have a total tax burden of 7.2% relative to their wealth. Their tax burden relative to wealth is much higher than for the top 0.1% because the bottom 99% relies primarily on labor income, which bears tax but is not part of net worth. In contrast, the majority of the income of the top 0.1% wealthiest comes from returns to their wealth.

Note: Our analysis complies with the highest levels of transparency and reproducibilty for open policy analysis proposed by the Berkeley Initiative for Transparency in the Social Sciences. We invite contributors and critics of this analysis to follow similar standards.

References


  1. The authors would like to particularly acknowledge the excellent research assitanship of Katie Donnelly Moran and Clancy Green.↩︎

  2. This dynamic document is part of an Open Policy Analysis which follows the guidelines of the Berkeley Initiative for Transparency in the Social Sciences↩︎

  3. With r=5.5%, we have [1+(1+r)+..+(1+r)^9]=[(1+r)^10-1]/r=12.9, or approximately 13.↩︎

  4. Saez, Emmanuel and Gabriel Zucman, “Wealth Inequality in the United States since 1913: Evidence from Capitalized Income Tax Data”, Quarterly Journal of Economics 131(2), 2016, 519-578, updated series available at http://gabriel-zucman.eu/usdina/↩︎

LS0tDQojIFRvIGNvbXBpbGUgaW50byAuZG9jIGZvcm1hdCwgcGxlYXNlIHNlZSB0aGlzIHR1dG9yaWFsOiBBREQgTElOSw0KdGl0bGU6ICI8Y2VudGVyPjxkaXYgY2xhc3M9ICdteXRpdGxlJz5PcGVuIFBvbGljeSBBbmFseXNpcyBGb3IgU2VuYXRvciBXYXJyZW4ncyBXZWFsdGggVGF4IDwvZGl2PjwvY2VudGVyPiINCmRhdGU6ICI8Y2VudGVyPjxkaXYgY2xhc3M9J215c3VidGl0bGUnPmByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgPC9kaXY+PC9jZW50ZXI+Ig0KYXV0aG9yOg0KLSAnUG9saWN5IEFuYWx5c2lzOiBFbW1hbnVlbCBTYWV6ICAmIEdhYnJpZWwgWnVjbWFuW14xXScNCi0gJ0R5bmFtaWMgRG9jdW1lbnQ6IEZlcm5hbmRvIEhvY2VzIGRlIGxhIEd1YXJkaWFbXjJdJw0KLSAnW0xpc3Qgb2YgYWxsIGNvbnRyaWJ1dG9yc10oaHR0cHM6Ly9naXRodWIuY29tL2Zob2Nlcy9vcGEtd2VhbHRodGF4L2Jsb2IvbWFzdGVyL2NyZWRpdHMubWQpIHRvIHRoZSBlbnRpcmUgT3BlbiBQb2xpY3kgQW5hbHlzaXMnDQoNCm91dHB1dDoNCiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOg0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNzczogc3R5bGUuY3NzDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgIGluY2x1ZGVzOg0KICAgICAgYWZ0ZXJfYm9keTogZm9vdGVyLmh0bWwNCiAgICBrZWVwX21kOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IG5vDQogICAgdGhlbWU6IHNhbmRzdG9uZQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogbm8NCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnMycNCiAgd29yZF9kb2N1bWVudDogbnVsbA0KbGluay1jaXRhdGlvbnM6IHllcw0KcGRmX2RvY3VtZW50Og0KICBleHRyYV9kZXBlbmRlbmNpZXM6IHhjb2xvcg0KICBmaWdfY2FwdGlvbjogbm8NCmJpYmxpb2dyYXBoeTogYmlibGlvZ3JhcGh5LmJpYg0KDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9IA0KIyBMb2FkaW5nIHJlcXVpcmVkIGxpYnJhcmllcw0KbGlzdC5vZi5wYWNrYWdlcyA8LSBjKCJ0aWR5dmVyc2UiLCAiaGF2ZW4iLCAiaGVyZSIsICJnZ3ZpcyIsICJrYWJsZUV4dHJhIiwgJ2Jvb2tkb3duJywNCiAgICAgICAgICAgICAgICAgICAgICAicm9vdFNvbHZlIiwic2hpbnlCUyIsICJzaGlueXRoZW1lcyIsImdncGxvdDIiKQ0KDQpuZXcucGFja2FnZXMgPC0gbGlzdC5vZi5wYWNrYWdlc1shKGxpc3Qub2YucGFja2FnZXMgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKVssIlBhY2thZ2UiXSldDQppZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgaW5zdGFsbC5wYWNrYWdlcyhuZXcucGFja2FnZXMsIHJlcG9zPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnIikNCg0KbGFwcGx5KGxpc3Qub2YucGFja2FnZXMsIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkNCg0KDQprbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9IGhlcmUoKSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCg0KcHJpbnRfY29kZSA8LSBUUlVFDQpgYGAgDQoNCmBgYHtyIG5vdGVzfQ0KIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjICBOb3RlczoNCiMjIyMjIyMjIyMjIyMjIyMgDQojIyMgU291cmNlIC0tLS0tLS0tLS0+ICBJbnB1dCAtLS0tLS0tLS0tPiAgTW9kZWwgLS0tLS0tLS0tLT4gIFBvbGljeSBFc3RpbWF0ZXMgKG91dHB1dCkNCiMjIyAgKF9zbykgICAgICAgICAgICAgIChfaW4pICAgICAgICAgICAgICAoX21vKSAgICAgICAgICAgICAgICAoX3BlKQ0KIyMjIHZhbHVlcyAgICAgICAgICAgIGZ1bmN0aW9ucyAgICAgICAgICBmdW5jdGlvbnMgICAgICAgICAgICAgIHZhbHVlcw0KIyMjICAgICAgICAgICAgICAgICAgICYgdmFsdWVzICAgICAgICAgICAmIHZhbHVlcyAgICAgICAgICAgICANCiMgLSBjYWxsX3NvdXJjZXNfZi0gdGF4X2VsYXN0aWNpdHlfaW5fZiAgLSB0YXhfcmV2ZW51ZV9tb19mICAgICAtIHRlbl95ZWFyX3JldmVudWVfcGUNCiMgLSBwb2xpY3lfZiAgICAgIC0gZXN0X2JpbGxpb25hcmVzX2luX2YgLSB0b3RhbF9yZXZfbW9fZiAgICAgICAtIHRlbl95ZWFyX3RvcF90YXhfcGUNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSB0ZW5feWVhcnNfbW9fZiAgICAgICAtIHRvdGFsX3Jldl9wZQ0KIyMjIGFyZ3VtZW50cyBpbiBmdW5jdGlvbnMgc2hvdWxkIHVzZWQgIl92YXIiIGFuZCBmdW5jdGlvbnMgc2hvdWxkICJfZiINCg0KDQojIERFU0NSSUJFIEZVTkNUSU9OUyBTVFJVQ1RVUkUNCiMgLSBpbnB1dHM6IGxpc3QNCiMgLSBvdXRwdXRzOiBsaXN0DQojIyMjIGZ1bmN0aW9uOiAgDQojc2FtcGxlX2Z1bmN0aW9uX2YgPC0gZnVuY3Rpb24oKXsNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgDQojDQojICAgIC4uLg0KIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiMgICAgcmV0dXJuKCApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQSBsaXN0IHdpdGggYWxsIChtb3N0PykgdGhlIGVsZW1lbnRzIA0KI30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBnZW5lcmF0ZWQgaW5zaWRlIHRoZSBmdW5jdGlvbiANCiNpbnZpc2libGUoIGxpc3QyZW52KHNhbXBsZV9mdW5jdGlvbl9mKCksLkdsb2JhbEVudikgKSANCiMNCmBgYA0KDQpgYGB7ciBzb3VyY2VzLCBlY2hvPXByaW50X2NvZGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9IA0KIyAtIGlucHV0czogbm9uZQ0KIyAtIG91dHB1dHM6IGFsbCB0aGUgb3JpZ2luYWwgc291cmNlIHZhbHVlcw0KY2FsbF9zb3VyY2VzX2YgPC0gZnVuY3Rpb24oKXsNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAgDQoNCiAgICAjIyMjIyMjIyMjIyMjIyMjICANCiAgICAjIyMjIyMjIFJlc2VhcmNoOg0KICAgICMjIyMjIyMjIyMjIyMjIyMgIA0KICAgIHJlc2VhcmNoX3NvIDwtIHJlYWRfY3N2KCJyYXdkYXRhL2VkaXRzL3Jlc2VhcmNoLmNzdiIpICAgICAgI2xvYWQgZGF0YSBzZXQgdGhhdCBjb250YWlucyBwYXJhbWV0ZXJzIGZyb20gcmVzZWFyY2gNCiAgICAjIEVsYXN0aWNpdGllcw0KICAgIGVsYTFfc28gPC0gYXMubnVtZXJpYyhyZXNlYXJjaF9zb1sxLCJwYXJhbSJdKSAgICAgICAgICAgIyAwLjUgLSBEYXZpZC4gMjAxNw0KICAgIGVsYTJfc28gPC0gYXMubnVtZXJpYyhyZXNlYXJjaF9zb1syLCJwYXJhbSJdKSAgICAgICAgICAgIyAwLjUgLSBKYWtvYnNlbiBldCBhbC4gMjAxOA0KICAgIGVsYTNfMV9zbyA8LSBhcy5udW1lcmljKHJlc2VhcmNoX3NvWzMsInBhcmFtIl0pICAgICAgICAgIyAyICAgLSBMb25kb25vLVZlbGV6IDIwMTgNCiAgICBlbGEzXzJfc28gPC0gICBhcy5udW1lcmljKHJlc2VhcmNoX3NvWzQsInBhcmFtIl0pICAgICAgICMgMyAgIC0gTG9uZG9uby1WZWxleiAyMDE4DQogICAgZWxhNF8xX3NvIDwtIGFzLm51bWVyaWMocmVzZWFyY2hfc29bNSwicGFyYW0iXSkgICAgICAgICAjIDIzICAtIEJyw7xsaGFydCBldCBhbC4gMjAxNg0KICAgIGVsYTRfMl9zbyA8LSBhcy5udW1lcmljKHJlc2VhcmNoX3NvWzYsInBhcmFtIl0pICAgICAgICAgIyAzNCAgLSBCcsO8bGhhcnQgZXQgYWwuIDIwMTYNCiAgICANCiAgICAjIyMjIyMjIyMjIyMjIyMjDQogICAgIyMjIyMjIERhdGE6DQogICAgIyMjIyMjIyMjIyMjIyMjIyANCiAgICBkZl9mb3JiZXNfc28gPC0gcmVhZF9kdGEoInJhd2RhdGEvZm9yYmVzXzIwMTEyMDE4X2JkYXlzLmR0YSIpICAjIEZvcmJlcw0KICAgIGRmX3NjZl9zbyA8LSByZWFkX2R0YSgicmF3ZGF0YS9yc2NmcDIwMTYuZHRhIikgICAgICAgICAgICAgICAgICMgU0NGDQogICAgZGZfZGluYTFfc28gPC0gcmVhZF9kdGEoImFuYWx5c2lzX2RhdGEvZGluYS5kdGEiKSAgICAgICAgICAgICAgIyBESU5BDQogICAgIyBUaGUgc291cmNlIGRhdGEgZmlsZSBmb3IgRElOQSBpcyBjb25maWRlbnRpYWwuIEluc3RydWN0aW9ucyANCiAgICAjIHRvIG9idGFpbiBpdCBhcmUgaW4gY29kZSBjaHVuayBvZiBzZWN0aW9uICMzLiAgICAgICAgICAgICAgIA0KDQogICAgIyBUb3RhbCB3ZWFsdGggYW5kIG51bWJlciBvZiBob3VzZWhvbGRzIFtTT1VSQ0UgTkVFREVEXQ0KICAgIHRvdGFsX2hobGRzX3NvIDwtIDEyOS40ZTYgICMgW1NPVVJDRV0NCiAgICAjIE1hY3JvZWNvbm9teS9kZW1vZ3JhcGhpY3MNCiAgICBpbmZsYXRpb25fc28gPC0gMC4wMjUgICAgICAjIENCTy9KQ1QNCiAgICBwb3B1bGF0aW9uX2dyX3NvIDwtIDAuMDEgICAjIENCTy9KQ1QgDQogICAgcmVhbF9ncm93dGhfc28gPC0gMC4wMiAgICAgIyBDQk8vSkNUDQogICAgaGhsZF9ncl9zbyA8LSAwLjAwOSAgICAgICAgIyBbU09VUkNFXQ0KICAgIA0KICAgICMjIyMjIyMjIyMjIyMjIyMgDQogICAgIyMjIyMgIEd1ZXNzd29yazoNCiAgICAjIyMjIyMjIyMjIyMjIyMjIA0KICAgIA0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiAgICByZXR1cm4oIHNhcHBseSggbHMocGF0dGVybj0gIl9zb1xcYiIpLCBmdW5jdGlvbih4KSBnZXQoeCkgKSApIA0KfQ0KaW52aXNpYmxlKCBsaXN0MmVudihjYWxsX3NvdXJjZXNfZigpLC5HbG9iYWxFbnYpICkNCg0KYGBgDQoNCmBgYHtyIG1haW4tcGUtcHJpbnQsIG91dC53aWR0aCA9ICcxMDAlJywgZmlnLmFsaWduPSdjZW50ZXInLCBlY2hvPUZBTFNFLCBwdXJsPUZBTFNFfQ0KIyB1cmwNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKHBhdGggPSBwYXN0ZTAoaGVyZSgpLCIvY29kZS9tYWluX3BlLnBuZyIpKQ0KYGBgDQpUYXggcmV2ZW51ZSBmcm9tIHdlYWx0aCB0YXggaW4gZmlyc3QgeWVhcjogJDE5OSBiaWxsaW9uDQpUYXggcmV2ZW51ZSBmcm9tIHdlYWx0aCB0YXggb3ZlciAxMCB5ZWFyOiAkMi42IHRyaWxsaW9uDQoNClBlcmNlbnRhZ2Ugb2YgVVMgaG91c2Vob2xkcyBwYXlpbmcgdGhlIHdlYWx0aCB0YXg6IDAuMDUlDQoNCioqW0NsaWNrIGhlcmVdKGh0dHA6Ly93ZWFsdGh0YXhzaW11bGF0b3Iub3JnL3NpbXVsYXRvcl9hcHAvKSB0byBleHBsb3JlIGRpZmZlcmVudCBwb2xpY3kgcHJvcG9zYWxzIGFuZCB0byBzZWUgaG93IHRoZSBhc3N1bXB0aW9ucyBvZiB0aGUgYW5hbHlzaXMgYWZmZWN0IHRoZSByZXN1bHRzLioqDQoNCioqVGhlcmUgYXJlIHR3byB3YXlzIHRvIGVkaXQgdGhlIGNvZGUgYmVoaW5kIHRoaXMgZG9jdW1lbnQ6KiogICANCjEgLSBEb3dubG9hZC9DbG9uZSBbdGhpcyByZXBvc2l0b3J5XShodHRwczovL2dpdGh1Yi5jb20vZmhvY2VzL29wYS13ZWFsdGh0YXgpIGludG8geW91ciBjb21wdXRlci4gWW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIFtSXShodHRwczovL2Nsb3VkLnItcHJvamVjdC5vcmcvKSBhbmQgW1JTdHVkaW9dKGh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQvI2Rvd25sb2FkKS4gICAgDQoNCjIgLSBHbyB0byBbdGhpcyBsaW5rXShodHRwczovL215YmluZGVyLm9yZy92Mi9naC9maG9jZXMvb3BhLXdlYWx0aHRheC9tYXN0ZXI/dXJscGF0aD1yc3R1ZGlvKSBhbmQgcmVwcm9kdWNlIGFsbCB0aGUgcmVzdWx0cyBpbiBhIGNvbXB1dGluZyBlbnZpcm9tZW50IChzdXBwb3J0ZWQgYnkgW3Byb2plY3QgYmluZGVyXShodHRwczovL215YmluZGVyLm9yZy8pKS4gWW91IHdpbGwgKipub3QqKiBuZWVkIHRvIGluc3RhbGwgYW55dGhpbmcgaW4geW91ciBjb21wdXRlci4gIA0KDQoNCg0KPGRpdiBjbGFzcyA9ICJkaXZpZGVyIj48c3Bhbj48L3NwYW4+PHNwYW4+DQpFeGVjdXRpdmUgU3VtbWFyeQ0KPC9zcGFuPjxzcGFuPjwvc3Bhbj48L2Rpdj4NCg0KSU5TRVJUIEVYRUMgU1VNTUFSWSBIRVJFDQoNCjxkaXYgY2xhc3MgPSAiZGl2aWRlciI+PHNwYW4+PC9zcGFuPjxzcGFuPg0KKg0KPC9zcGFuPjxzcGFuPjwvc3Bhbj48L2Rpdj4NCg0KDQoNCiMgT3BlbiBQb2xpY3kgQW5hbHlzaXMgey19DQoNCklOU0VSVCBPUEEgVEhJTkcgSEVSRQ0KDQojIFBvbGljeSBjaG9pY2VzIA0KDQpUaGUgd2VhbHRoIHRheCBhcHBsaWVzIHRvIG5ldCB3b3J0aCAoc3VtIG9mIGFsbCBhc3NldHMgbmV0IG9mIGRlYnRzKSBhYm92ZSAkNTAgbWlsbGlvbiwgYW5kIG9iZXlzIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOg0KDQpgYGB7ciBwb2xpY3ksIGVjaG89cHJpbnRfY29kZX0gDQojIC0gaW5wdXRzOiBub25lIA0KIyAtIG91dHB1dHM6IGFsbCB0aGUgb3JpZ2luYWwgc291cmNlIHZhbHVlcw0KIyMjIyBQb2xpY3k6ICANCnBvbGljeV9mIDwtIGZ1bmN0aW9uKCl7DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgDQogIA0KICAgICMgYnJhY2tldHNfcG8NCiAgICBicmFja2V0c19wbyA8LSBjKDEwLCAyNSwgNTAsIDEwMCwgMjUwLCA1MDAsICAxMDAwKSAqIDFlNg0KICAgIHRheF9yYXRlc19wbyA8LSBjKCAgMCwgICAgMCwgMC4wMiwgIDAuMDIsICAwLjAyLCAgMC4wMiwgMC4wMykgDQogICAgc3RhcnRpbmdfYnJhY2tfcG8gPC0gYnJhY2tldHNfcG9bbWluKHdoaWNoKHRheF9yYXRlc19wbz4wKSldDQogICAgbmV4dF9pbmNyZWFzZV9wbyA8LSBicmFja2V0c19wb1ttaW4od2hpY2godGF4X3JhdGVzX3BvPjAuMDIpKV0NCiAgICBtYWluX3RheF9wbyA8LSBtZWRpYW4odGF4X3JhdGVzX3BvKQ0KICAgIG1heF90YXhfcG8gPC0gbWF4KHRheF9yYXRlc19wbykNCiAgICANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiAgICByZXR1cm4oIHNhcHBseSggbHMocGF0dGVybj0gIl9wb1xcYiIpLCBmdW5jdGlvbih4KSBnZXQoeCkpICkgDQp9DQppbnZpc2libGUoIGxpc3QyZW52KHBvbGljeV9mKCksLkdsb2JhbEVudikgKQ0KDQprbml0cjo6a2FibGUoY2JpbmQoIkJyYWNrZXQgKG1pbGxpb25zIG9mICQpIiA9IGJyYWNrZXRzX3BvLzFlNiwNCiAgICAgICAgICAgICAgICAgICAiTWFyZ2luYWwgVGF4IFJhdGUgKCUpIiA9IDEwMCp0YXhfcmF0ZXNfcG8pICklPiUNCiAga2FibGVfc3R5bGluZygpICANCmBgYCAgDQoNCkhvdXNlaG9sZCBuZXQgd29ydGggYWJvdmUgYHIgcGFzdGUwKCIkIiwgc3RhcnRpbmdfYnJhY2tfcG8vMWU3KWAgbWlsbGlvbiB3b3VsZCBiZSB0YXhlZCBhdCBgciBwYXN0ZShtYWluX3RheF9wbyAqIDEwMCwgIiUiLCBzZXAgPSAiIilgLiBBbnkgd2VhbHRoIG92ZXIgYHIgcGFzdGUwKCIkIiwgbmV4dF9pbmNyZWFzZV9wby8xZTkpYCBiaWxsaW9uIHdvdWxkIGJlIHRheGVkIGFuIGFkZGl0aW9uYWwgMSUgKGEgYmlsbGlvbmFpcmUgc3VydGF4KS4NCg0KIyBDb21wdXRlIHRheCBhdm9pZGFuY2UgZWxhc3RpY2l0eSANCg0KVG8gY2FsY3VsYXRlIHRoZSByZXZlbnVlIGZyb20gdGhpcyB3ZWFsdGggdGF4LCB0aGUgZXh0ZW50IG9mIHdlYWx0aCB0YXggZXZhc2lvbi9hdm9pZGFuY2UgaXMgZXN0aW1hdGVkIGJhc2VkIG9uIHJlY2VudCByZXNlYXJjaCBzaG93aW5nIHRoYXQgaXQgZGVwZW5kcyBjcnVjaWFsbHkgb24gbG9vcGhvbGVzIGFuZCBlbmZvcmNlbWVudC4gVGhlIHRheC1hdm9pZGFuY2UgZWxhc3RpY2l0eSBpcyBjb21wdXRlZCBhcyB0aGUgYXZlcmFnZSBlbGFzdGljaXR5IGZyb20gZm91ciBzdHVkaWVzLiBUaGUgdGFibGUgbGlzdHMgdGhlIGZvdXIgc3R1ZGllcyBhbmQgdGhlIGF2b2lkYW5jZS9ldmFzaW9uIHJlc3BvbnNlIHRvIGEgMSUgd2VhbHRoIHRheC4NCg0KYGBge3IgYXZvaWRhbmNlLXRhYmxlLCBlY2hvPUZBTFNFfQ0KIyBFWFBMQUlOIHRoYXQgdGhpcyBpcyBmb3IgZGlzcGxheSBvbmx5IGluIHRoaXMgY2h1bmsuIE5vdCBuZWVkZWQgbGF0ZSBvbi4gDQojIEZvcm1hdCB0aGUgcGFyYW1ldGVycyBmcm9tIHJlc2VhcmNoIGludG8gb25lIHRhYmxlDQphdXgxX2RmIDwtICAgcmVzZWFyY2hfc28gJT4lIA0KICBncm91cF9ieShwYXBlcl9pZCkgJT4lIA0KICBtdXRhdGUoYXV4MSA9IHJvd19udW1iZXIoKSkgJT4lIA0KICBmaWx0ZXIoYXV4MSA9PTEpICU+JSANCiAgdW5ncm91cCgpICU+JSAgDQogIHNlbGVjdChBdXRob3JzLCBZZWFyLCBwYXBlciwgUHVibGlzaGVyKSANCmF1eDIgPC0gYyhlbGExX3NvLCBlbGEyX3NvLCBwYXN0ZTAoZWxhM18xX3NvLCAiLSIsIGVsYTNfMl9zbyksIHBhc3RlMChlbGE0XzFfc28sICItIiwgZWxhNF8yX3NvKSkNCnRhYmxlX2F1eCA8LSBjYmluZChhdXgxX2RmLCAgIkF2b2lkYW5jZS9ldmFzaW9uIHJlc3BvbnNlIiA9IGF1eDIpIA0Ka25pdHI6OmthYmxlKHRhYmxlX2F1eCwgZm9ybWF0ID0gImh0bWwiLCBib29rdGFicyA9IFQpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFKQ0KYGBgDQoNClNlaW0gKDIwMTcpIGFuZCBKYWtvYnNlbiBldCBhbC4gKDIwMTgpIG9idGFpbiBzbWFsbCBhdm9pZGFuY2UvZXZhc2lvbiByZXNwb25zZXMgaW4gdGhlIGNhc2Ugb2YgU3dlZGVuIGFuZCBEZW5tYXJrLCB0d28gY291bnRyaWVzIHdpdGggc3lzdGVtYXRpYyB0aGlyZCBwYXJ0eSByZXBvcnRpbmcgb2Ygd2VhbHRoOiBhIDElIHdlYWx0aCB0YXggcmVkdWNlcyByZXBvcnRlZCB3ZWFsdGggYnkgbGVzcyB0aGFuIDElLiBMb25kb25vLVZlbGV6IGFuZCBBdmlsYSAoMjAxOCkgc2hvdyBtZWRpdW0gYXZvaWRhbmNlL2V2YXNpb24gcmVzcG9uc2VzIGluIHRoZSBjYXNlIG9mIENvbG9tYmlhIHdoZXJlIGVuZm9yY2VtZW50IGlzIG5vdCBhcyBzdHJvbmc6IGEgMSUgd2VhbHRoIHRheCByZWR1Y2VzIHJlcG9ydGVkIHdlYWx0aCBieSBhYm91dCBgciBwYXN0ZShlbGEzXzFfc28sICItIiwgZWxhM18yX3NvLCIlIiwgc2VwPSIiKWAuIFRoZSBzdHVkeSBvbiBTd2l0emVybGFuZCBieSBCcsO8bGhhcnQgZXQgYWwuICgyMDE2KSBpcyBhbiBvdXRsaWVyIHRoYXQgZmluZHMgdmVyeSBsYXJnZSByZXNwb25zZXMgdG8gd2VhbHRoIHRheGF0aW9uIGluIFN3aXR6ZXJsYW5kOiBhIDElIHdlYWx0aCB0YXggbG93ZXJzIHJlcG9ydGVkIHdlYWx0aCBieSBgciBwYXN0ZShlbGE0XzFfc28sICItIiwgZWxhNF8yX3NvLCIlIiwgc2VwPSIiKWAuIFRoaXMgZXh0cmVtZWx5IGxhcmdlIGVzdGltYXRlIGlzIGV4dHJhcG9sYXRlZCBmcm9tIHZlcnkgc21hbGwgdmFyaWF0aW9ucyBpbiB3ZWFsdGggdGF4IHJhdGVzIG92ZXIgdGltZSBhbmQgYWNyb3NzIFN3aXNzIGNhbnRvbnMgYW5kIGhlbmNlIGlzIG5vdCBhcyBjb21wZWxsaW5nbHkgaWRlbnRpZmllZCBhcyB0aGUgb3RoZXIgZXN0aW1hdGVzIGJhc2VkIG9uIGxhcmdlIHZhcmlhdGlvbnMgaW4gdGhlIHdlYWx0aCB0YXggcmF0ZS4gU3dpdHplcmxhbmQgaGFzIG5vIHN5c3RlbWF0aWMgdGhpcmQgcGFydHkgcmVwb3J0aW5nIG9mIGFzc2V0cyB3aGljaCBjYW4gYWxzbyBtYWtlIHRheCBldmFzaW9uIHJlc3BvbnNlcyBsYXJnZXIgdGhhbiBpbiBTY2FuZGluYXZpYS4gDQoNCmBgYHtyIHRheC1lbGFzdGljaXR5LCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPXByaW50X2NvZGV9ICAgDQojIGlucHV0OiBlbGFzdGljaXR5IHBhcmFtZXRlcnMgZnJvbSByZXNlYXJjaCwgbWFpbiB0YXgsIGFkanV0bWVudCBmYWN0b3INCiMgb3VwdHV0OiBmaW5hbCBlbGFzdGljaXR5IChmaW5hbF9lbGFfaW4pLCBldmFzaW9uIHBhcmFtZXRlciAoZXZhc2lvbl9wYXJhbV9pbikgIA0KdGF4X2VsYXN0aWNpdHlfaW5fZiA8LSBmdW5jdGlvbihlbGExX3ZhciA9IGVsYTFfc28sIGVsYTJfdmFyID0gZWxhMl9zbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsYTNfMV92YXIgPSBlbGEzXzFfc28sIGVsYTNfMl92YXIgPSBlbGEzXzJfc28sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGE0XzFfdmFyID0gZWxhNF8xX3NvLCBlbGE0XzJfdmFyID0gZWxhNF8yX3NvLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWluX3RheF92YXIgPSBtYWluX3RheF9wbyl7DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgDQogIA0KICAgIGZpbmFsX2VsYV9pbiA8LSBtZWFuKGMoZWxhMV92YXIsIGVsYTJfdmFyLCAoZWxhM18xX3ZhciArIGVsYTNfMl92YXIpLzIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVsYTRfMV92YXIgKyBlbGE0XzJfdmFyKS8yKSkNCiAgICBldmFzaW9uX3BhcmFtX2luIDwtIG1haW5fdGF4X3ZhciAqIGZpbmFsX2VsYV9pbg0KICAgIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgIA0KICAgIHJldHVybihsaXN0KCJmaW5hbF9lbGFfaW4iID0gZmluYWxfZWxhX2luLCANCiAgICAgICAgICAgICAgICAiZXZhc2lvbl9wYXJhbV9pbiIgPSBldmFzaW9uX3BhcmFtX2luKSkNCn0NCmludmlzaWJsZSggbGlzdDJlbnYodGF4X2VsYXN0aWNpdHlfaW5fZigpLC5HbG9iYWxFbnYpICkgDQpgYGANCg0KVGhlIGZpbmFsIGByIHBhc3RlMChldmFzaW9uX3BhcmFtX2luICogMTAwLCIlIilgIHRheCBhdm9pZGFuY2UvZXZhc2lvbiByZXNwb25zZSB0byBhIGByIHBhc3RlMChtYWluX3RheF9wbyAqIDEwMCwgIiUiKWAgd2VhbHRoIHRheCB3YXMgY29tcHV0ZWQgYXMgYW5kIGF2ZXJhZ2UgYWNyb3NzIHRoZXNlIGZvdXIgc3R1ZGllcyAoYHIgcGFzdGUwKG1haW5fdGF4X3BvICogMTAwLCAiJSIsICIqKCIsIGVsYTFfc28sICIrIiwgZWxhMl9zbywgIisiICwoZWxhM18xX3NvK2VsYTNfMl9zbykvMiwgIisiLCAoZWxhNF8xX3NvK2VsYTRfMl9zbykvMiwgIikvNCIpYCkuDQoNCiMgRGF0YSBzb3VyY2VzIA0KVGhyZWUgZGF0YSBzb3VyY2VzIHdlcmUgdXNlZCBpbiB0aGlzIGFuYWx5c2lzOiAgIA0KDQogLSBbRGlzdHJpYnV0aW9uYWwgTmF0aW9uYWwgQWNjb3VudHMgKERJTkEpXShodHRwOi8vZ2FicmllbC16dWNtYW4uZXUvdXNkaW5hLyk6IGVzdGltYXRlcyB3ZWFsdGggYnkgY2FwaXRhbGl6aW5nIGludmVzdG1lbnQgaW5jb21lIGZyb20gaW5jb21lIHRheCByZXR1cm5zLiBMYXRlc3QgeWVhciBhdmFpbGFibGU6IDIwMTkuICAgIA0KIC0gW1N1cnZleSBvZiBDb25zdW1lciBGaW5hbmNlcyAoU0NGKV0oaHR0cHM6Ly93d3cuZmVkZXJhbHJlc2VydmUuZ292L2Vjb25yZXMvc2NmaW5kZXguaHRtKSBmcm9tIHRoZSBGZWRlcmFsIFJlc2VydmUgQm9hcmQuIE1vc3QgcmVjZW50IHllYXIgYXZhaWxhYmxlOiAyMDE2LiAgICANCiAtIFtGb3JiZXMgNDAwXShodHRwczovL3d3dy5mb3JiZXMuY29tL2ZvcmJlcy00MDAvIzRkMzU4YWNmN2UyZik6IHByb3ZpZGVzIHRoZSBiZXN0IGVzdGltYXRlIG9mIGJpbGxpb25hcmVzIGluIHRoZSBVUy4gTW9zdCByZWNlbnQgeWVhciBhdmFpbGFibGU6IDIwMTguICANCg0KIyMgRGF0YSBjbGVhbmluZyANCg0KRnJvbSBlYWNoIGRhdGEgc2V0IHRocmVlIHZhcmlhYmxlIHdlcmUgZXh0cmFjdGVkOiBgbmV0d29ydGhgIHRoYXQgY29udGFpbiBpbmZvcm1hdGlvbiBvbiB3ZWFsdGgsIGB3ZWlnaHRzYCByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgaG91c2Vob2xkcyB0aGF0IGVhY2ggb2JzZXJ2YXRpb24gcmVwcmVzZW50cyBhbmQgYGRhdGFgIHdoaWNoIHRyYWNrcyB0aGUgZGF0YSBvZiBvcmlnaW4uDQoNClRoZSBmb2xsb3dpbmcgdHJhbnNmb3JtYXRpb25zIHdlcmUgYXBwbGllZCB0byB0aGUgZGF0YTogICAgICANCg0KIC0gRWFjaCBvYnNlcnZhdGlvbiBpbiBESU5BIGlzIGFnZ3JlZ2F0ZWQgaW50byBncm91cHMgb2YgNSBvYnNlcnZhdGlvbnMgdG8gYW5vbnltaXplIHRoZSBkYXRhLiAgDQogLSBTQ0Ygd2FzIGFnZWQgYnkgaW5mbGF0aW5nIHRoZSBudW1iZXIgb2YgaG91c2Vob2xkcyBhbmQgd2VhbHRoIHVuaWZvcm1seSB0byBtYXRjaCB0aGUgbW9zdCByZWNlbnQgYWdncmVnYXRlIHByb2plY3Rpb25zIGZvciBwb3B1bGF0aW9uIGFuZCB0b3RhbCBob3VzZWhvbGQgd2VhbHRoIGZyb20gdGhlIEZlZGVyYWwgUmVzZXJ2ZSBCb2FyZC4gIEFmdGVyIHRoYXQsIFNDRiB3ZWFsdGggd2FzIHNjYWxlZCB0byBtYXRjaCB0aGUgdG90YWwgb2YgRElOQSBtaW51cyB0aGUgd2VhbHRoIG9mIEZvcmJlcyAodG8gcHJldmVudCBkb3VibGUgY291bnRpbmcgb2Ygd2VhbHRoKS4gICANCiAtIEFmdGVyIGNvbWJpbmluZyAoYXBwZW5kaW5nKSBhbGwgdGhyZWUgZGF0YSBzb3VyY2VzLCB0aGUgcG9wdWxhdGlvbiB3ZWlnaHRzIG9mIFNDRiBhbmQgRElOQSB3aGVyZSBjb21iaW5lZCBieSB0aGUgdGFraW5nIHRoZSBhdmVyYWdlIG9mIHRoZSB0d28uICAgDQoNCg0KYGBge3IgZGF0YS1jbGVhbmluZywgZXZhbD1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPXByaW50X2NvZGV9ICANCiMjIyMjIFJlcHJvZHVjaW5nIGRvIGZpbGUgKCd3ZWFsdGh0YXguZG8nKQ0KIyBpbnB1dHM6IA0KIyBvdXRwdXRzOiBkZl9mb3JiZXMxX2luLCBkZl9kaW5hMV9pbiwgZGZfc2NmMV9pbiwgZGZfaW4sIHRvdGFsX3dlYWx0aF9zY2ZfaW4sDQojIHRvdGFsX3dlYWx0aF9pbg0KY2xlYW5fZGF0YV9mIDwtIGZ1bmN0aW9uKGRmX2ZvcmJlc192YXIgPSBkZl9mb3JiZXNfc28sIGRmX2RpbmExX3ZhciA9IGRmX2RpbmExX3NvLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3NjZl92YXIgPSBkZl9zY2Zfc28pew0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KICAgICMjIyBGb3JiZXMgZGF0YSANCiAgICBkZl9mb3JiZXMxX2luIDwtIGRmX2ZvcmJlc192YXIgICU+JSAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgZmlsdGVyKGZvcmJlc195ciA9PSAyMDE4KSAlPiUgDQogICAgICBtdXRhdGUoIm5ldHdvcnRoIiA9IG5ldF93b3J0aG1pbGxpb25zICogMWU2LCANCiAgICAgICAgICAgICAgICJ3ZWlnaHQiID0gMSwgDQogICAgICAgICAgICAgICAiZGF0YSIgPSAiRkI0MDAiKSAlPiUNCiAgICAgIHNlbGVjdChkYXRhLCBuZXR3b3J0aCwgd2VpZ2h0KSAlPiUgDQogICAgICBmaWx0ZXIoICFpcy5uYShuZXR3b3J0aCkgKQ0KICAgIGZvcmJlc21pbiA8LSBtaW4oZGZfZm9yYmVzMV9pbiRuZXR3b3J0aCkNCiAgICBmNDAwdG90IDwtIHN1bShkZl9mb3JiZXMxX2luJG5ldHdvcnRoICogZGZfZm9yYmVzMV9pbiR3ZWlnaHQpIC8gMWUxMiAgDQogICAgI2NhdCgiVE9UQUwgRk9SQkVTIE5FVFdPUlRIIDIwMTggKFRyKSA9ICIsIGY0MDB0b3QsICAiRk9SQkVTIE1JTiBXRUFMVEggMjAxOCA9ICIsIGZvcmJlc21pbikNCiAgICANCiAgICAjIyMgRElOQSBkYXRhIA0KICAgICMjIyMjIyMgVGhpcyBzZWN0aW9uIHVzZXMgZGF0YSB0aGF0IGNhbm5vdCBiZSBzaGFyZWQgZm9yIGNvbmZpZGVudGlhbGl0eSByZWFzb25zDQogICAgIyMjIyMjIyBCZWxvdyBpcyB0aGUgY29kZSB1c2VkIHRvIGFnZ3JlZ2F0ZSB0aGUgZGF0YS4NCiAgICAjIyMjIyMjIElmIHlvdSBoYXZlIGFjY2VzcyB0byB0aGUgb3JnaW5hbCBkYXRhIHNldCwgc2V0IGlzX2RpbmFfcHVibGljX3NvID0gVFJVRS4NCiAgICAjIyMjIyMjIFRvIG9idGFpbiB0aGlzIGRhdGEgcGxlYXNlIGNvbnRhY3QgR2FicmllbCBadWNtYW4gYXQgenVjbWFuQGdtYWlsLmNvbQ0KICAgICMjIyMjIyMgVGhlIGZpbGUgdGhhdCB5b3Ugd2lsbCBvYnRhaW4gc2hvdWxkIGhhdmUgdGhlIGZvbGxvd2luZyBzaWduYXR1cmU6DQogICAgIyMjIyMjIyBpbiBSOiBkaWdlc3QoInVzZGluYTIwMTkuZHRhIiwgZmlsZSA9IFRSVUUpIHByb2R1Y2VzOiANCiAgICAjIyMjIyMjICIyZjVkNTI5YjFlODllMzkxNzE5MjdkYzI4YmZlYmJlNCINCiAgICAjIyMjIyMjIGluIFN0YXRhLCBkYXRhc2lnbmF0dXJlIHByb2R1Y2VzOiANCiAgICAjIyMjIyMjICIyODI4NjY6NCg0OTYyOCk6NDA4MzI3OTcwODoxODA2NTg2OTA3Ig0KICAgIA0KICAgICMgV2l0aCBhY2Nlc3MgdG8NCiAgICAjIHByaXZhdGUgRElOQSwgc2V0IGluZGljYXRvciB0byBiZWxvdyB0byBUUlVFDQogICAgaXNfZGluYV9wdWJsaWMgPC0gRkFMU0UgICAgICAgICAgICAgICAgICAgICAgICANCiAgICBpZihpc19kaW5hX3B1YmxpYyl7DQogICAgICAjIHBhc3RlIGJlbG93IHRoZSBwYXRoIHRvIHdoZXJlIHVzZGluYTIwMTkuZHRhIGlzIGluIHlvdXIgY29tcHV0ZXINCiAgICAgIHBhdGhfdG9fZGluYSA8LSBwYXN0ZTAoIkhFUkVfR09FU19ZT1VSX1BBVEgiLCAiL3VzZGluYTIwMTkuZHRhIikNCiAgICAgIGRmX2RpbmFfc28gPC0gcmVhZF9kdGEocGF0aF90b19kaW5hKQ0KICAgICAgZGZfZGluYSA8LSBkZl9kaW5hX3NvICU+JSANCiAgICAgIGdyb3VwX2J5KGlkKSAlPiUgDQogICAgICBzdW1tYXJpc2UoIm5ldHdvcnRoIiA9IHJvdW5kKHN1bShod2VhbCkpLCAgIyByb3VuZGluZyBvZiBuZXR3b3J0aCBpcyB0byBtYWtlIGl0IGNvbXBhdGlibGUgd2l0aCBTdGF0YQ0KICAgICAgICAgICAgICAgICJ3ZWlnaHQiID0gbWVhbihkd2VnaHQpLzFlNSkgDQogICAgICAgIA0KICAgICAgdG90d19kaW5hIDwtIHN1bShkZl9kaW5hJG5ldHdvcnRoICogZGZfZGluYSR3ZWlnaHQpIC8gMWUxMg0KICAgICAgI2NhdCgiVE9UQUwgRElOQSBORVRXT1JUSCAyMDE5ICAoVHIpICIsIHRvdHdfZGluYSkNCiAgICAgIA0KICAgICAgdG90bl9kaW5hIDwtIHN1bShkZl9kaW5hJHdlaWdodCkNCiAgICAgIA0KICAgICAgZGZfZGluYSRkYXRhIDwtICJESU5BIg0KICAgICAgDQogICAgICAjIEFnZ3JlZ2F0ZSBpbnRvIGJpbnMgb2YgNSBob3VzZWhvZGxzIGluZm8gdG8gcHJvdGVjdCBjb25maWRlbnRpYWxpdHkNCiAgICAgIGRmX2RpbmExIDwtIGRmX2RpbmEgJT4lIA0KICAgICAgICBtdXRhdGUoImF1eF9pZCIgPSAxOmRpbShkZl9kaW5hKVsxXSkgJT4lIA0KICAgICAgICBhcnJhbmdlKGRlc2MobmV0d29ydGgpLGF1eF9pZCkgJT4lIA0KICAgICAgICAjIFN0aWxsIG5vdCBjbGVhciB3aGF0IHRoZSByb2xlIG9mIHRoZSAiKzMiIGlzLiAgDQogICAgICAgIG11dGF0ZSgiZ3JvdXAiID0gZmxvb3IoKDE6ZGltKGRmX2RpbmEpWzFdICsgMykgLyA1KSkgJT4lIA0KICAgICAgICBncm91cF9ieShncm91cCkgJT4lIA0KICAgICAgICBzdW1tYXJpc2UoIndlaWdodCIgPSBzdW0od2VpZ2h0KSwNCiAgICAgICAgICAgICAgICAgICJuZXR3b3J0aCIgPSBtZWFuKG5ldHdvcnRoKSkgJT4lIA0KICAgICAgICBtdXRhdGUoImRhdGEiID0gIkRJTkEiKSAlPiUgDQogICAgICAgIHNlbGVjdCgiZGF0YSIsICJuZXR3b3J0aCIsICJ3ZWlnaHQiKQ0KICAgICAgd3JpdGVfZHRhKCJhbmFseXNpc19kYXRhL2RpbmEuZHRhIiwgZGF0YSA9IGRmX2RpbmExKQ0KICAgICAgZGZfZGluYTFfaW4gPC0gcmVhZF9kdGEoImFuYWx5c2lzX2RhdGEvZGluYS5kdGEiKQ0KICAgIH0gZWxzZSB7DQogICAgICBkZl9kaW5hMV9pbiA8LSBkZl9kaW5hMV92YXIgDQogICAgfQ0KICAgICMjIyMgRW5kIG9mIGNvbmZpZGVudGlhbCBzZWN0aW9uDQogICAgdG90d19kaW5hIDwtIHN1bShkZl9kaW5hMV9pbiRuZXR3b3J0aCAqIGRmX2RpbmExX2luJHdlaWdodCkgLyAxZTEyDQogICAgIyMjIFNDRiBkYXRhIA0KICAgIA0KICAgICMgSW5jcmVhc2UgdGhlIHBvcHVsYXRpb24gd2VpZ3RocyB0byByZWZsZWN0IHBvcHVsYXRpb24gZ3Jvd3RoIGZyb20gMjAxNiB0byAxMDE5DQogICAgZGZfc2NmX3ZhciA8LSBkZl9zY2ZfdmFyICU+JSANCiAgICAgICAgICBtdXRhdGUoIndndDIwMTkiID0gcm91bmQoIHdndCAqICgxICsgaGhsZF9ncl9zbyleKCAyMDE5IC0gMjAxNiApKSkNCiAgICB0b3R3IDwtIHN1bShkZl9zY2ZfdmFyJG5ldHdvcnRoICogZGZfc2NmX3ZhciR3Z3QyMDE5KSAvIDFlMTINCiAgICB0b3RuIDwtIHN1bShkZl9zY2ZfdmFyJHdndDIwMTkpDQogICAgdG90d19zY2YgPC0gc3VtKGRmX3NjZl92YXIkbmV0d29ydGggKiBkZl9zY2ZfdmFyJHdndCkgLyAxZTEyDQogICAgI2NhdCgiVE9UQUwgU0NGIE5FVFdPUlRIIDIwMTYgIChUcikiLCB0b3R3X3NjZikNCiAgICANCiAgICAjIFJlc2NhbGluZyBTQ0YgdG8gbWF0Y2ggdG90YWwgdG90YWwgd2VhbHRoIHJlcG9ydGVkIGluIERJTkEgZXhjbHVkaW5nIHRoZSBmNDAwDQogICAgZGZfc2NmMV9pbiA8LSBkZl9zY2ZfdmFyICU+JSBtdXRhdGUoIm5ldHdvcnRoIiA9IG5ldHdvcnRoICogKCB0b3R3X2RpbmEgLSBmNDAwdG90ICkgLyB0b3R3LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndlaWdodCIgPSB3Z3QyMDE5LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiID0gIlNDRiIpICU+JQ0KICAgICAgc2VsZWN0KGRhdGEsIG5ldHdvcnRoLCB3ZWlnaHQpDQogICAgDQogICAgIyBDb21iaW5lIHRocmVlIGRhdGEgc291cmNlcw0KICAgIGRmIDwtIHJiaW5kKGRmX2ZvcmJlczFfaW4sIGRmX3NjZjFfaW4sIGRmX2RpbmExX2luKQ0KICAgIA0KICAgICMgSWYgb2JzZXJ2YXRpb24gaXMgaW4gU0NGIG9yIERJTkEsIHRoZW4gZGl2aWRlIHRoZWlyIHdlaWdodHMgaW4gMg0KICAgIGRmJHdlaWdodCA8LSB3aXRoKGRmLCBpZmVsc2UoZGF0YT09IlNDRiIgfCBkYXRhPT0iRElOQSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZCh3ZWlnaHQvMiksIHdlaWdodCkgKQ0KICAgICMgQWxsIG9icyBmcm9tIFNDRiBhbmQgRElOQSB0aGF0IGhhdmUgd2VhbHRoIGFib3ZlIHRoZSBtaW4gb2YgZm9yYmVzIGFyZSBkcm9wZWQgdG8gYXZvaWQgZHVwbGljYXRpb25zDQogICAgZGZfaW4gPC0gZGYgJT4lIGZpbHRlciggIShuZXR3b3J0aCA+IGZvcmJlc21pbiAmICggZGF0YSA9PSAiU0NGIiB8IGRhdGEgPT0gIkRJTkEiICkgKSApDQogICAgDQogICAgIyBkZiAlPiUgDQogICAgIyAgIHN1bW1hcmlzZSggbWVhbihuZXR3b3J0aCksIHNkKG5ldHdvcnRoKSApIA0KICAgIA0KICAgIHRvdGFsX3dlYWx0aCA8LSBkZl9pbiAlPiUgDQogICAgICBzdW1tYXJpc2Uoc3VtKG5ldHdvcnRoICogd2VpZ2h0KSAvIDFlMTIpICU+JSANCiAgICAgIGFzLm51bWVyaWMoKQ0KICAgIGZpZnR5X21pbGxpb193ZWFsdGggPC0gZGZfaW4gJT4lIA0KICAgICAgZmlsdGVyKG5ldHdvcnRoID49IDUwZTYpICU+JSANCiAgICAgIHN1bW1hcmlzZShzdW0obmV0d29ydGggKiB3ZWlnaHQpIC8gMWUxMikgJT4lIA0KICAgICAgYXMubnVtZXJpYygpDQogICAgDQogICAgI2NhdCgiVG90YWwgd2VhbHRoIChpbiB0cmlsbGlvbnMpIGlzICIsIHRvdGFsX3dlYWx0aCwgIi4gV2VhbHRoIGZvciBiaWxsaW9uYXJlcyB0b3RhbCB3ZWFsdGggaXMgIiwgZmlmdHlfbWlsbGlvX3dlYWx0aCkgDQogICAgDQogICAgd3JpdGVfZHRhKCJhbmFseXNpc19kYXRhL3dlYWx0aC5kdGEiLCBkYXRhID0gZGZfaW4sIHZlcnNpb24gPSAxMSkNCiAgICANCiAgICAjIFZlcnkgc21hbGwgZGlmZmVyZW5jZXMgd2l0aCBzdGF0YSBvdXRwdXQgKGJ1dCBpdCBzaG91bGQgYmUgemVybyBkaWZmZXJlbmNlcykNCiAgICAjIHdlYWx0aCA8LSByZWFkX2R0YSgifi9Eb3dubG9hZHMvd2VhbHRodGF4c2ltL2RhdGEvd2VhbHRoLmR0YSIpDQogICAgIyBkaWZmX2F1eCA8LSBhYnMoIGRmX2luJG5ldHdvcnRoIC0gIHdlYWx0aCRuZXR3b3J0aCApDQogICAgIyBzdW1tYXJ5KGFicyhkaWZmX2F1eCkpDQogICAgIyAgICAgTWluLiAgMXN0IFF1LiAgIE1lZGlhbiAgICAgTWVhbiAgM3JkIFF1LiAgICAgTWF4LiANCiAgICAjICAgIDAuMDAwICAgIDAuMDAwICAgIDAuMDA4ICAgIDAuOTI4ICAgIDAuMTc0IDMzMjguMDAwIA0KICAgIA0KICAgIHRvdGFsX3dlYWx0aF9zY2ZfaW4gPC0gZGZfc2NmX3ZhciAlPiUgDQogICAgICBzdW1tYXJpc2Uoc3VtKG5ldHdvcnRoICogd2d0KS8xZTEyKSAlPiUgIA0KICAgICAgYXMubnVtZXJpYygpDQogICAgdG90YWxfd2VhbHRoX2luIDwtIGRmX2luICU+JSAgDQogICAgICBzdW1tYXJpc2Uoc3VtKG5ldHdvcnRoICogd2VpZ2h0KS8xZTEyKSAlPiUgIA0KICAgICAgYXMubnVtZXJpYygpDQogICAgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiAgICAgcmV0dXJuKGxpc3QoImRmX2ZvcmJlczFfaW4iID0gZGZfZm9yYmVzMV9pbiwgImRmX2RpbmExX2luIiA9IGRmX2RpbmExX2luLCANCiAgICAgImRmX3NjZjFfaW4iID0gZGZfc2NmMV9pbiwgImRmX2luIiA9IGRmX2luLCAidG90YWxfd2VhbHRoX3NjZl9pbiIgPSB0b3RhbF93ZWFsdGhfc2NmX2luLCANCiAgICAgInRvdGFsX3dlYWx0aF9pbiIgPSB0b3RhbF93ZWFsdGhfaW4pKQ0KfQ0KaW52aXNpYmxlKGxpc3QyZW52KGNsZWFuX2RhdGFfZigpLC5HbG9iYWxFbnYpICkgDQpgYGANCg0KVGhlIHRvdGFsIGhvdXNlaG9sZCBuZXQgd29ydGggcHJvamVjdGlvbiBpcyBgciBwYXN0ZTAoIiQiLCByb3VuZCh0b3RhbF93ZWFsdGhfaW4pKWAgdHJpbGxpb24gZm9yIDIwMTkgKHRoZSBTQ0YgcmVjb3JkcyBhIHRvdGFsIGhvdXNlaG9sZCBuZXQgd29ydGggb2YgYHIgcGFzdGUwKCIkIiwgcm91bmQodG90YWxfd2VhbHRoX3NjZl9pbikpYCB0cmlsbGlvbiBpbiAyMDE2KS4NCg0KIyMgR2VuZXJhdGluZyAgcGVyY2VudGlsZXMgYW5kIG1pY3JvLXBlcmNlbnRpbGVzIA0KDQpJbiB0aGlzIHNlY3Rpb24sIHRoZSBtaWNyb2RhdGEgZ2VuZXJhdGVkIGJlZm9yZSAoYHdlYWx0aC5kdGFgKSBpcyBhZ2dyZWdhdGVkIGludG8gcGVyY2VudGlsZXMgYW5kIGZyYWN0aW9ucyBvZiBhIHBlcmNlbnRpbGUuIFRoZSBmaW5hbCBhbmFseXRpYyBmaWxlIGNvbnRhaW5zOiBwZXJjZW50aWxlIG9yIGZyYWN0aW9uIG9mIHBlcmNlbnRpbGUgKGBncGVyY2ApLCBudW1iZXIgb2YgaG91c2Vob2xkcyBpbiB0aGF0IGdyb3VwIChgbmJgKSwgbG93ZXN0IGxldmVsIG9mIHdlYWx0aCBpbiB0aGF0IGdyb3VwIChgdGhyZXNgKSwgYW5kIGF2ZXJhZ2UgbGV2ZWwgb2Ygd2VhbHRoIGluIHRoYXQgZ3JvdXAgKGBhdmdgKSAgDQoNCmBgYHtyIHN0YXRhLWNvZGUsIGV2YWw9RkFMU0UsIGVjaG89cHJpbnRfY29kZX0NCiojIFRoZSBjb2RlIGJlbG93IGRvZXMgbm90IHJ1biBhcyBwYXJ0IG9mIHRoZSBkeW5hbWljIGRvY3VtZW50IGFuZCBpcyBwcmVzZW50ZWQgb25seQ0KKiMgZm9yIHJlcHJvZHVjaWJpbGl0eSBwdXJwb3Nlcy4NCiojIFRvIHJ1biB0aGUgY29kZSBiZWxvdyB5b3Ugd2lsbCByZXF1aXJlIGEgbGljZW5zZSBvZiBTdGF0YSAxMSBvciBoaWdoZXIuIFlvdSB3aWxsIGFsc28gbmVlZCB0byANCiojIHBsYWNlIGEgY29weSBvZiB0aGUgZmlsZSAnZ3BlcmMuYWRvJywgbG9jYXRlZCBpbiB0aGUgJ3Jhd2RhdGEnIGZvbGRlciBvZiB0aGlzIHJlcG9zaXRvcnkgDQoqIyBpbnRvIHlvdXIgYWRvIGZvbGRlci4gICANCiojIHBhc3RlIHRoZSBkaXJlY3Rvcnkgb2YgdGhlIHJlcG9zaXRvcnkgaW4geW91ciBjb21wdXRlciBiZWxvdzogDQpnbG9iYWwgIHJlcG9zaXRvcnkgICAiWU9VUiBQQVRIIEhFUkUiDQoNCnN5c2RpciBzZXQgUEVSU09OQUwgIiRyZXBvc2l0b3J5L3Jhd2RhdGEvIg0KDQoqIGNyZWF0aW5nIGFuIGV4Y2VsIHRhYmxlIGZvciB0aGUgc2ltdWxhdGlvbg0KdXNlICRyZXBvc2l0b3J5L2FuYWx5c2lzX2RhdGEvd2VhbHRoLmR0YSwgY2xlYXINCmNhcCBnZW4gYXV4X2lkID0gX24NCnNvcnQgYXV4X2lkDQpncGVyYyBuZXR3b3J0aCBbdz13ZWlnaHRdLCBtYXRuYW1lKHdlYWx0aHBlcmMpCQ0KbWF0IGxpc3Qgd2VhbHRocGVyYwkNCmNsZWFyDQpzdm1hdCB3ZWFsdGhwZXJjLCBuYW1lcyhjb2wpDQpxdWkgY29tcHJlc3MNCmV4cG9ydCBkZWxpbWl0ZWQgdXNpbmcgIiRyZXBvc2l0b3J5L2FuYWx5c2lzX2RhdGEvdGF4X2dyaWQuY3N2IiwgcmVwbGFjZQ0KYGBgDQoNCiMgTnVtYmVyIG9mIGFmZmVjdGVkIGhvdXNlaG9sZHMgYW5kIHRoZWlyIHRvdGFsIHRheCBiYXNlIA0KDQpUbyBjb21wdXRlIHRoZSByZWxldmFudCB1bml2ZXJzZSB0aGUgZXZhc2lvbiBwYXJhbWV0ZXIgb2YgYHIgcGFzdGUwKGV2YXNpb25fcGFyYW1faW4gKjEwMCwgIiUiKWAgaXMgYXBwbGllZCB0byBib3RoIHRoZSB0aHJlc2hvbGQgYW5kIHRoZSBhdmVyYWdlIHdlYWx0aCBvZiBlYWNoIHBlcmNlbnRpbGUgKGFuZCBmcmFjdGlvbiBvZiBhIHBlcmNlbnRpbGUpDQoNCmBgYHtyIGFmZmVjdGVkIGhobGRzLCBldmFsPVRSVUUsIGVjaG89cHJpbnRfY29kZX0gIA0KIyBERVNDUklCRSBGVU5DVElPTlMgU1RSVUNUVVJFDQojIC0gaW5wdXRzOiBsaXN0DQojIC0gb3V0cHV0czogbGlzdA0KIyMjIyBmdW5jdGlvbjogIA0KI3NhbXBsZV9mdW5jdGlvbl9mIDwtIGZ1bmN0aW9uKCl7DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiMNCiMgICAgLi4uDQojDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiMgICAgcmV0dXJuKCApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KI2ludmlzaWJsZSggbGlzdDJlbnYoc2FtcGxlX2Z1bmN0aW9uX2YoKSwuR2xvYmFsRW52KSApDQoNCmdyaWQgPC0gcmVhZC5jc3YoImFuYWx5c2lzX2RhdGEvdGF4X2dyaWQuY3N2IikgICU+JSANCiAgZmlsdGVyKCFpcy5uYShncGVyYykpDQoNCiMgV2VhbHRoIHBlciBiaW4gKHBlcmNlbnRpbGUpIGFmdGVyIGV2YXNpb24gIA0KZ3JpZCR0aHJlc05ldyA8LSAoMSAtIGV2YXNpb25fcGFyYW1faW4pICogZ3JpZCR0aHJlcw0KZ3JpZCRhdmdOZXcgPC0gKDEgLSBldmFzaW9uX3BhcmFtX2luKSAqIGdyaWQkYXZnIA0KDQojIyMjIyBOdW0gaGhsZHM6DQojbm8gYXZvaWRhbmNlDQp0YXJnZXRfaGhsZHNfbm9hdl9tbyA8LSBncmlkICU+JSANCiAgZmlsdGVyKHRocmVzID4gc3RhcnRpbmdfYnJhY2tfcG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bShuYikpDQoNCiN3aXRoIGF2b2lkYW5jZQ0KdGFyZ2V0X2hobGRzX21vIDwtIGdyaWQgJT4lIA0KICBmaWx0ZXIodGhyZXNOZXcgPiBzdGFydGluZ19icmFja19wbykgJT4lIA0KICBzdW1tYXJpc2Uoc3VtKG5iKSkNCg0KIyMjIEJpbGxpb25hcmVzOg0KI25vIGF2b2lkYW5jZQ0KdGFyZ2V0X2hobGRzX2JuX25vYXZfbW8gPC0gZ3JpZCAlPiUgDQogIGZpbHRlcih0aHJlcyA+IG5leHRfaW5jcmVhc2VfcG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bShuYikpDQoNCiN3aXRoIGF2b2lkYW5jZQ0KdGFyZ2V0X2hobGRzX2JuX21vIDwtIGdyaWQgJT4lIA0KICBmaWx0ZXIodGhyZXNOZXcgPiBuZXh0X2luY3JlYXNlX3BvKSAlPiUgDQogIHN1bW1hcmlzZShzdW0obmIpKQ0KDQojIyMjIyBUb3RhbCBUYXhhYmxlIFdlYWx0aDoNCnRheF9iYXNlX3RvdGFsX25vYXZfbW8gPC0gZ3JpZCAlPiUgDQogIGZpbHRlcih0aHJlcyA+IHN0YXJ0aW5nX2JyYWNrX3BvKSAlPiUgDQogIHN1bW1hcmlzZShzdW0oKGF2ZyAtIHN0YXJ0aW5nX2JyYWNrX3BvKSAqIG5iKS8xZTEyKQ0KDQojd2l0aCBhdm9pZGFuY2UNCiMyJSBhYm92ZSA1MG0NCnRheF9iYXNlX3RvdGFsX21vIDwtIGdyaWQgJT4lIA0KICBmaWx0ZXIodGhyZXNOZXcgPiBzdGFydGluZ19icmFja19wbykgJT4lIA0KICBzdW1tYXJpc2Uoc3VtKChhdmdOZXcgLSBzdGFydGluZ19icmFja19wbykgKiBuYikvMWUxMikNCg0KI2JpbGxpb25hcmVzIGFkZGl0aW9uYWwgMSUNCnRheF9iYXNlX3RvdGFsX3N1cnRheF9ub2F2X21vIDwtIGdyaWQgJT4lIA0KICBmaWx0ZXIodGhyZXMgPiBuZXh0X2luY3JlYXNlX3BvKSAlPiUgDQogIHN1bW1hcmlzZShzdW0oKGF2ZyAtIG5leHRfaW5jcmVhc2VfcG8pICogbmIpLzFlMTIpDQp0YXhfYmFzZV90b3RhbF9zdXJ0YXhfbW8gPC0gZ3JpZCAlPiUgDQogIGZpbHRlcih0aHJlc05ldyA+IG5leHRfaW5jcmVhc2VfcG8pICU+JSANCiAgc3VtbWFyaXNlKHN1bSgoYXZnTmV3IC0gbmV4dF9pbmNyZWFzZV9wbykgKiBuYikvMWUxMikNCg0KIyByb3VuZGluZyBudW1iZXIgdG8gZGlzcGxheSBpbiB0aGUgbmV4dCBwYXJhZ3JhcGhzDQp0YXJnZXRfaGhsZHNfbm9hdl9yb3VuZCA8LSBmb3JtYXQocm91bmQodGFyZ2V0X2hobGRzX25vYXZfbW8gLyAxMDAwKSAqIDEwMDAgLCBzY2llbnRpZmljID0gRkFMU0UpDQp0YXJnZXRfaGhsZHNfcm91bmQgPC0gZm9ybWF0KHJvdW5kKHRhcmdldF9oaGxkc19tbyAvIDEwMDApICogMTAwMCwgc2NpZW50aWZpYyA9IEZBTFNFKQ0KdGFyZ2V0X2hobGRzX2JuX25vYXZfcm91bmQgPC0gcm91bmQodGFyZ2V0X2hobGRzX2JuX25vYXZfbW8gLyAxMDAwKSAqIDEwMDAgDQp0YXJnZXRfaGhsZHNfYm5fcm91bmQgPC0gcm91bmQodGFyZ2V0X2hobGRzX2JuX21vIC8gMTAwMCkgKiAxMDAwIA0KYGBgDQoNCkluIDIwMTksIHRoZXJlIHdvdWxkIGJlIGFyb3VuZCBgciAgdGFyZ2V0X2hobGRzX3JvdW5kYCBob3VzZWhvbGRzIGxpYWJsZSBmb3IgdGhlIHdlYWx0aCB0YXggKGByIHRhcmdldF9oaGxkc19ub2F2X3JvdW5kYCBiZWZvcmUgYWNjb3VudGluZyBmb3IgYXZvaWRhbmNlKS4gVGhpcyB3b3VsZCBiZSBsZXNzIHRoYW4gYHIgcGFzdGUwKHJvdW5kKHRhcmdldF9oaGxkc19tby90b3RhbF9oaGxkc19zbyAqIDEwMCAsIGRpZ2l0cyA9IDIpLCAiJSIpYCBvZiB0aGUgYHIgcm91bmQodG90YWxfaGhsZHNfc28vMWU3KSAqIDEwYCBtaWxsaW9uIFVTIGhvdXNlaG9sZHMgaW4gMjAxOS4gDQoNCiMjIGByIHBhc3RlMChtYWluX3RheF9wbyAqIDEwMCwgIiUiKWAgdGF4IG9uIGFsbCB3ZWFsdGggYWJvdmUgYHIgcGFzdGUwKCIkIixzdGFydGluZ19icmFja19wby8xZTYpYCBtaWxsaW9ucw0KDQpUaGUgYHIgdGFyZ2V0X2hobGRzX21vYCBob3VzZWhvbGRzIHdpdGggYXNzZXN0cyB0b3RhbGluZyBvdmVyIGByIHBhc3RlMCgiJCIsc3RhcnRpbmdfYnJhY2tfcG8vMWU2KWAgbWlsbGlvbiB3b3VsZCBoYXZlIGEgdG90YWwgdGF4YWJsZSB3ZWFsdGggKGFib3ZlIHRoZSBgciBwYXN0ZTAoIiQiLHN0YXJ0aW5nX2JyYWNrX3BvLzFlNiwgIm1pbGxpb24iKWApIG9mIGByIHBhc3RlKCIkIiwgcm91bmQodGF4X2Jhc2VfdG90YWxfbW8sIGRpZ2l0cyA9IDEpLCBzZXA9IiIpYCB0cmlsbGlvbiwgIGkuZS4gYXBwcm94aW1hdGVseSBgciBwYXN0ZTAocm91bmQodGF4X2Jhc2VfdG90YWxfbW8vdG90YWxfd2VhbHRoX2luKiAxMDApLCAiJSIpYCAgb2YgdGhlIGByIHBhc3RlMCgiJCIsIHJvdW5kKHRvdGFsX3dlYWx0aF9pbikpYCB0cmlsbGlvbiBwb3B1bGF0aW9uLXdpZGUsIHRvdGFsIGhvdXNlaG9sZCBuZXQgd29ydGguDQoNCiMjIGByIHBhc3RlMCgobWF4X3RheF9wbyAtIG1haW5fdGF4X3BvKSAqIDEwMCwgIiUiKWAgYWRkaXRpb25hbCB0YXggb24gYWxsIHdlYWx0aCBhYm92ZSBgciBwYXN0ZTAoIiQiLG5leHRfaW5jcmVhc2VfcG8vMWU5KWAgYmlsbGlvbg0KDQpUaGUgYHIgdGFyZ2V0X2hobGRzX2JuX21vYCBob3VzZWhvbGRzIHdpdGggYXNzZXN0cyB0b3RhbGluZyBvdmVyIGByIHBhc3RlMCgiJCIsbmV4dF9pbmNyZWFzZV9wby8xZTkpYCBiaWxsaW9uIGRvbGxhcnMgd291bGQgaGF2ZSBhIHRvdGFsIHRheGFibGUgd2VhbHRoIChhYm92ZSB0aGUgYHIgcGFzdGUwKCIkIixuZXh0X2luY3JlYXNlX3BvLzFlOSwgImJpbGxpb24iKWApIG9mIGByIHBhc3RlKCIkIiwgcm91bmQodGF4X2Jhc2VfdG90YWxfc3VydGF4X21vLCBkaWdpdHMgPSAxKSwgc2VwPSIiKWAgdHJpbGxpb24sICBpLmUuIGFwcHJveGltYXRlbHkgYHIgcGFzdGUwKHJvdW5kKHRheF9iYXNlX3RvdGFsX3N1cnRheF9tby90b3RhbF93ZWFsdGhfaW4qIDEwMCksICIlIilgICBvZiB0aGUgYHIgcGFzdGUwKCIkIiwgcm91bmQodG90YWxfd2VhbHRoX2luKSlgIHRyaWxsaW9uIHBvcHVsYXRpb24td2lkZSwgdG90YWwgaG91c2Vob2xkIG5ldCB3b3J0aC4NCg0KDQojIFRvdGFsIHRheCByZXZlbnVlIGluIG9uZSB5ZWFyIA0KDQpgYGB7ciBuZXctdGF4LXJldiwgZXZhbD1UUlVFLCBlY2hvPXByaW50X2NvZGV9IA0KIyBERVNDUklCRSBGVU5DVElPTlMgU1RSVUNUVVJFDQojIC0gaW5wdXRzOiBsaXN0DQojIC0gb3V0cHV0czogbGlzdA0KIyMjIyBmdW5jdGlvbjogIA0KI3NhbXBsZV9mdW5jdGlvbl9mIDwtIGZ1bmN0aW9uKCl7DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiMNCiMgICAgLi4uDQojDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICANCiMgICAgcmV0dXJuKCApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQojfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KI2ludmlzaWJsZSggbGlzdDJlbnYoc2FtcGxlX2Z1bmN0aW9uX2YoKSwuR2xvYmFsRW52KSApDQoNCg0KDQogDQojIFRvdGFsIHRheCBjb2xsZWN0ZWQgaW4gYSB5ZWFyDQojIGFtb3VudCBmcm9tIDIlDQojIGFtb3VudCBmcm9tIGV4dHJhIDElDQoNCiNUaGlzIGZ1bmN0aW9uIGNvbXB1dGVzIHRoZSB0b3RhbCB0YXggY29sbGVjdGVkIGZvciBhIHRheCB1bml0IHdpdGggd2VhbHRoICJ3ZWFsdGhfdmFyIiwgYXBwbHlpbmcgInRheHJhdGVzX3ZhciIgdG8gImJyYWNrZXRzX3ZhciINCiMgLSBpbnB1dHM6IHdlYWx0aCwgdGF4IHJhdGVzLCBicmFja2V0cyB0byB0YXgNCiMgLSBvdXB1dHM6IHRvdGFsIHRheCBjb2xsZWN0ZWQNCmdldF90YXhfcmV2IDwtIGZ1bmN0aW9uKHdlYWx0aF92YXIgPSB3ZWFsdGhfYXV4LCB0YXhyYXRlc192YXIgPSB0YXhfcmF0ZXNfcG8sDQogICAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXRzX3ZhciA9IGJyYWNrZXRzX3BvKSB7DQogICAgIyMgZXhwZWN0aW5nIHRheExldmVscyBpbiBwZXJjZW50YWdlDQogICAgIyB0YXhMZXZlbHMgPC0gdGF4TGV2ZWxzIC8gMTAwDQogICAgaWYgKGxlbmd0aChicmFja2V0c192YXIpICE9IGxlbmd0aCh0YXhyYXRlc192YXIpKXsNCiAgICAgIHN0b3AoIlRheCBicmFja2V0cyBhbmQgdGF4IHJhdGVzIGRvIG5vdCBtYXRjaCIpDQogICAgfQ0KICAgIyBDb21wdXRlIG1heCB0YXhhYmxlIHdlYWx0aCBwZXIgYnJhY2tldA0KICAgIG1heF90YXhfcGVyX2JyYWNrIDwtIGMoZGlmZihjKDAsIGJyYWNrZXRzX3ZhcikpLCAxZTEwMCkNCiAgICMgU3Vic3RyYWN0IHdlYWx0aCBtaW51cyB0YXggYnJhY2tldC4gSWYgd2VhbHRoIGFib3ZlIGEgZ2l2ZW4gYnJhY2tldCAoZGlmZmVyZW5jZSBpcyBsYXJnZXIgdGhhbiBtYXggdGF4YWJsZSB3ZWFsdGgpLCANCiAgICMgdGhlbiBhc3NpZ24gbWF4IHRheGFibGUgd2VhbHRoIHRvIHRoYXQgZ2l2ZW4gYnJhY2tldA0KICAgIHRvX3RheCA8LSBpZmVsc2UoIHdlYWx0aF92YXIgLSBjKDAsIGJyYWNrZXRzX3ZhcikgPiBtYXhfdGF4X3Blcl9icmFjaywgDQogICAgICAgICAgICAgICAgICAgICAgbWF4X3RheF9wZXJfYnJhY2ssIA0KICAgICAgICAgICAgICAgICAgICAgICggd2VhbHRoX3ZhciAtIGMoMCxicmFja2V0c192YXIpICkgKSAgIA0KICAgIyBJZiB3ZWFsdGggaWYgbG93ZXIgdGhhbiBhIGdpdmVuIGJyYWNrZXQgKGRpZmZlcmVuY2UgYmV0d2VlbiB3ZWFsdGggYW5kIGJyYWNrZXQgaXMgbmVnYXRpdmUpLCB0aGVuIGFzc2lnbiB6ZXJvIHRvIHRoYXQgYnJhY2tldCAgDQogICAgdG9fdGF4IDwtIGlmZWxzZSggdG9fdGF4PDAsIDAsIHRvX3RheCApDQogICAgIyBBcHBseSB0cmF4IHJhdGVzIHRvIGVhY2ggY29ycmVzcG9uZGluZyBicmFja2V0IGFuZCBhbGwgdG9nZXRoZXINCiAgICB0b3RhbF90YXggPC0gc3VtKCB0b190YXggKiBjKDAsIHRheHJhdGVzX3ZhcikgKSAgIA0KICAgIHJldHVybih0b3RhbF90YXgpDQp9DQoNCiMgSU1QT1JUQU5UOiB0aGlzIChzaW1pbGFyIHRvIGdldFRheEJhc2VQZXJCcmFja2V0KSB3YXMgZGlmZmVyaW5nIGZyb20gc2ltcGxlDQojIGNhbGN1bGF0aW9uIGJlbG93IGJlY2F1c2UgdGhpcyB3YXMgbm90IHN1YnNldGluZyB0byB3ZWFsdGggYWJvdmUgNTBtLg0KIyBjb21wdXRlcyB0YXggcGF5ZWQgYnkgZWFjaCBhdmVyYWdlIHdlYWx0aCBwZXIgcGVyY2ludGlsZSAodXAgdG8gMiUpDQoNCiMjIGdldHMgdGF4ZXMgcGFpZCBwZXIgZ3JvdXAgKHBlcmNlbnRpbGUgYW5kIG1pY3JvcGVyY2VudGlsZSkNCmdldF90YXhfcmV2X3Blcl9ncm91cCA8LSBmdW5jdGlvbihncmlkX3ZhciA9IGdyaWQsIHRheExldmVsc192YXIgPSB0YXhfcmF0ZXNfcG8sIGJyYWNrZXRzX3ZhcjEgPSBicmFja2V0c19wbykgew0KICBncmlkX3ZhciA8LSBncmlkX3ZhciAlPiUgZmlsdGVyKHRocmVzTmV3ID4gc3RhcnRpbmdfYnJhY2tfcG8pDQogIGF1eF92YXIgPC0gc2FwcGx5KGdyaWRfdmFyJGF2Z05ldywgDQogICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkgZ2V0X3RheF9yZXYod2VhbHRoX3ZhciA9IHgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGF4cmF0ZXNfdmFyID0gdGF4TGV2ZWxzX3ZhciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFja2V0c192YXIgPSBicmFja2V0c192YXIxKSkNCiAgcmV0dXJuKHN1bShncmlkX3ZhciRuYiAqIGF1eF92YXIpIC8gMWU5KQ0KfQ0KDQp0YXhfcmV2X2luaXRfbW8gPC0gZ2V0X3RheF9yZXZfcGVyX2dyb3VwKHRheExldmVscyA9IGModGF4X3JhdGVzX3BvWy03XSwgMC4wMikpDQp0b3BfdGF4X3Jldl9pbiA8LSBnZXRfdGF4X3Jldl9wZXJfZ3JvdXAodGF4TGV2ZWxzID0gYyhyZXAoMCw2KSwgMC4wMSkpDQp0b3RhbF90YXhfcmV2IDwtIGdldF90YXhfcmV2X3Blcl9ncm91cCh0YXhMZXZlbHMgPSB0YXhfcmF0ZXNfcG8pDQojMTk5Ljc4ODkNCg0KIyBUaGUgZm9sbG93aW5nIHJlcGxpY2F0ZXMgc3RhdGEgY29kZSBtb3JlIGNsb3NlbHkgYW5kIHNlZW1zIG1vcmUgc3RyYWlnaHRmb3J3YXJkLiANCiMgSG93ZXZlcmUgaXQgZGlmZmVycyBtb3JlIGZyb20gdGhlIGNvZGUgaW4gdGhlIGFwcC4gQ29uc2lkZXIgdGhpcyBpbiBib3RoIChhcHAgYW5kIEREKQ0KIyBpbiB0aGUgZnV0dXJlDQppZiAoRkFMU0Upew0KICAgICN3aXRoIGF2b2lkYW5jZQ0KICAgICMyJSBhYm92ZSA1MG0NCiAgICB0YXhfcmV2X2luaXRfbW8gPC0gZ3JpZCAlPiUgDQogICAgICBmaWx0ZXIodGhyZXNOZXcgPiBzdGFydGluZ19icmFja19wbykgJT4lIA0KICAgICAgc3VtbWFyaXNlKHN1bSgoYXZnTmV3IC0gc3RhcnRpbmdfYnJhY2tfcG8pICogbmIgKiAwLjAyKS8xZTkpICU+JSBhcy5udW1lcmljKCkNCiAgICANCiAgICAjYmlsbGlvbmFyZXMgYWRkaXRpb25hbCAxJQ0KICAgIHRvcF90YXhfcmV2X2luIDwtIGdyaWQgJT4lIA0KICAgICAgZmlsdGVyKHRocmVzTmV3ID4gbmV4dF9pbmNyZWFzZV9wbykgJT4lIA0KICAgICAgc3VtbWFyaXNlKHN1bSgoYXZnTmV3IC0gbmV4dF9pbmNyZWFzZV9wbykgKiBuYiAqIDAuMDEpLzFlOSkgJT4lIGFzLm51bWVyaWMoKQ0KICAgIA0KICAgIHRvdGFsX3RheF9yZXYgPC0gdG90YWxfdGF4X2Jhc2UgKyB0b3RhbF90YXhfc3VyX2JpbGwNCn0NCg0KIyBUTyBERUxFVEUgQUxMIEJFTE9XPw0KZ2V0UGVvcGxlUGVyQnJhY2tldD1mdW5jdGlvbihncmlkLCBicmFja2V0cyl7DQogIGJyYWNrZXRzID0gYyhicmFja2V0cywgMWUxMikgIyMgZ2V0IGxhc3QgYnJhY2tldA0KICBncmlkJGdyb3VwPWN1dChncmlkJHRocmVzTmV3LCBicmFja2V0cykNCiAgdG9SZXR1cm4gPSBncmlkICU+JSANCiAgICBncm91cF9ieShncm91cCkgJT4lIA0KICAgIHN1bW1hcmlzZSh0b3RhbFBlb3BsZT1zdW0obmIpKSAlPiUgDQogICAgZHJvcF9uYSgpDQogIHJldHVybih0b1JldHVybikNCn0NCg0KbnVtYmVyVGF4cGF5ZXJzIDwtIGdldFBlb3BsZVBlckJyYWNrZXQoYnJhY2tldHMgPSBicmFja2V0c19wbywgZ3JpZCA9IGdyaWQpDQoNCiNSZXZlbnVlDQojRnJvbSBoZXJlIG9uOiBrZWVwDQp0YXJnZXRfaGhsZHNfbW8gPC0gc3VtKCBudW1iZXJUYXhwYXllcnMkdG90YWxQZW9wbGVbYnJhY2tldHNfcG8+PXN0YXJ0aW5nX2JyYWNrX3BvXSApDQoNCmBgYA0KDQpTdGFydGluZyB3aXRoIHRoZSBgciBwYXN0ZTAoIiQiLCByb3VuZCh0YXhfYmFzZV90b3RhbF9tbywgZGlnaXRzID0gMSkpYCB0cmlsbGlvbiB0YXggYmFzZSBvZiB3ZWFsdGggYWJvdmUgYHIgcGFzdGUwKCIkIiwgc3RhcnRpbmdfYnJhY2tfcG8vMWU2KWAgbWlsbGlvbiAoYHIgcGFzdGUwKCIkIiwgcm91bmQodGF4X2Jhc2VfdG90YWxfbm9hdl9tbywgZGlnaXRzID0gMSkpYCB3aXRoIG5vIGF2b2lkYW5jZSksIGEgYHIgcGFzdGUwKG1haW5fdGF4X3BvICogMTAwLCAiJSIpYCB0YXggd291bGQgcmFpc2UgYHIgcGFzdGUwKCIkIiwgcm91bmQodGF4X3Jldl9pbml0X21vKSlgIGJpbGxpb24gaW4gMjAxOS4gVGhlIGJpbGxpb25haXJlIHN1cnRheCBpcyBlc3RpbWF0ZWQgdG8gYXBwbHkgdG8gYSBiYXNlIG9mIGByIHBhc3RlMCgiJCIsIHJvdW5kKHRheF9iYXNlX3RvdGFsX3N1cnRheF9tbywgMSkpYCB0cmlsbGlvbiAoYHIgcGFzdGUwKCIkIiwgcm91bmQodGF4X2Jhc2VfdG90YWxfc3VydGF4X25vYXZfbW8sIGRpZ2l0cyA9IDEpKWAgd2l0aCBubyBhdm9pZGFuY2UpIGZyb20gYWJvdXQgYHIgcm91bmQodGFyZ2V0X2hobGRzX2JuX21vIC8gMTAwKSAqIDEwMCBgIGJpbGxpb25haXJlIGZhbWlsaWVzIChgciByb3VuZCh0YXJnZXRfaGhsZHNfYm5fbm9hdl9tbyAvIDEwMCkgKiAxMDAgYCAgd2l0aCBubyBhdm9pZGFuY2UpLiBUaHVzIHRoZSBiaWxsaW9uYWlyZSBzdXJ0YXggd291bGQgcmFpc2UgYHIgcGFzdGUwKCIkIiwgcm91bmQodG9wX3RheF9yZXZfaW4pKWAgYmlsbGlvbiBpbiAyMDE5LiBUaGUgY29tYmluYXRpb24gb2YgdGhlIGByIHBhc3RlMCgxMDAqbWFpbl90YXhfcG8sICIlIilgIHRheCBhYm92ZSBgciBwYXN0ZTAoIiQiLHN0YXJ0aW5nX2JyYWNrX3BvLzFlNilgIG1pbGxpb24gYW5kIHRoZSBiaWxsaW9uYWlyZSBzdXJ0YXggd291bGQgcmFpc2UgYHIgcGFzdGUwKHJvdW5kKHRheF9yZXZfaW5pdF9tbywxKSwiICsgIiwgcm91bmQodG9wX3RheF9yZXZfaW4sMSkpYCA9IGByIHJvdW5kKHRvdGFsX3RheF9yZXYsMSlgIGJpbGxpb24gaW4gMjAxOS4gDQoNCiMgVGVuIHllYXIgcHJvamVjdGlvbnMgIA0KDQpgYGB7ciB0ZW4teWVhcnMsIGVjaG89cHJpbnRfY29kZX0gIA0KIyAtIGlucHV0czogaW5mbGF0aW9uX3NvLCBwb3B1bGF0aW9uX2dyX3NvLCByZWFsX2dyb3d0aF9zbywgdG90YWxfcmV2X3BlLCB0b3BfdGF4X3Jldl9pbg0KIyAtIG91cHV0czogZGlzY291bnRfcmF0ZV9tbywgdGVuX3llYXJfZmFjdG9yX21vLCB0ZW5feWVhcl9yZXZlbnVlX3BlLCB0ZW5feWVhcl90b3BfdGF4X3BlDQp0ZW5feWVhcnNfbW9fZiA8LSBmdW5jdGlvbihpbmZsYXRpb25fdmFyID0gaW5mbGF0aW9uX3NvLCBwb3B1bGF0aW9uX2dyX3ZhciA9IHBvcHVsYXRpb25fZ3Jfc28sDQogICAgICAgICAgICAgICAgICAgICAgICAgICByZWFsX2dyb3d0aF92YXIgPSByZWFsX2dyb3d0aF9zbywgdG90YWxfcmV2X3ZhciA9IHRvdGFsX3RheF9yZXYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9wX3RheF9iYXNlX3ZhciA9IHRvcF90YXhfcmV2X2luKXsNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIA0KICAgIGRpc2NvdW50X3JhdGVfbW8gPC0gaW5mbGF0aW9uX3ZhciArIHBvcHVsYXRpb25fZ3Jfc28gKyByZWFsX2dyb3d0aF9zbyAgDQogICAgdGVuX3llYXJfZmFjdG9yX21vIDwtIHN1bSggKCAxICsgZGlzY291bnRfcmF0ZV9tbyApXiggMDo5ICkgKSANCg0KICAgIHRlbl95ZWFyX3JldmVudWVfcGUgPC0gdG90YWxfcmV2X3ZhciAqIHRlbl95ZWFyX2ZhY3Rvcl9tbyAgICAgDQogICAgI3Rlbl95ZWFyX3JldmVudWVfcGUgPC0gdG90YWxfcmV2X3BlICogdGVuX3llYXJfZmFjdG9yX21vICAgICAgICAgICAgICAgICAgICAgICNQRQ0KICAgIHRlbl95ZWFyX3RvcF90YXhfcGUgPC0gdG9wX3RheF9iYXNlX3ZhciAqIHRlbl95ZWFyX2ZhY3Rvcl9tbyAgICAgICAgICANCiAgICAjdGVuX3llYXJfdG9wX3RheF9wZSA8LSB0b3BfdGF4X2Jhc2VfdmFyICogdGVuX3llYXJfZmFjdG9yX21vICAgICAgICAgICAgICAgICAgI1BFDQogICAgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIA0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAgIHJldHVybiggbGlzdCgiZGlzY291bnRfcmF0ZV9tbyIgPSBkaXNjb3VudF9yYXRlX21vLCAidGVuX3llYXJfZmFjdG9yX21vIiA9IHRlbl95ZWFyX2ZhY3Rvcl9tbywgDQogICAgICAgICAgICJ0ZW5feWVhcl9yZXZlbnVlX3BlIiA9IHRlbl95ZWFyX3JldmVudWVfcGUsICJ0ZW5feWVhcl90b3BfdGF4X3BlIiA9IHRlbl95ZWFyX3RvcF90YXhfcGUpICkNCn0NCmludmlzaWJsZSggbGlzdDJlbnYodGVuX3llYXJzX21vX2YoKSwuR2xvYmFsRW52KSApDQpgYGANCg0KVG8gcHJvamVjdCB0YXggcmV2ZW51ZXMgb3ZlciBhIDEwLXllYXIgaG9yaXpvbiwgd2UgYXNzdW1lIHRoYXQgbm9taW5hbCB0YXhhYmxlIHdlYWx0aCB3b3VsZCBncm93IGF0IHRoZSBzYW1lIHBhY2UgYXMgdGhlIGVjb25vbXksIG9yIGByIHBhc3RlKDEwMCAqIGRpc2NvdW50X3JhdGVfbW8sIiUiLCBzZXA9IiIpYCBwZXIgeWVhciBhcyBpbiBzdGFuZGFyZCBwcm9qZWN0aW9ucyBvZiB0aGUgQ29uZ3Jlc3Npb25hbCBCdWRnZXQgT2ZmaWNlIG9yIHRoZSBKb2ludCBDb21taXR0ZWUgb24gVGF4YXRpb24uIFRoaXMgZ3Jvd3RoIGlzIGRlY29tcG9zZWQgaW50byBgciBwYXN0ZSgxMDAgKiBpbmZsYXRpb25fc28sIiUiLCBzZXA9IiIpYCBwcmljZSwgYHIgcGFzdGUoMTAwICogcm91bmQocG9wdWxhdGlvbl9ncl9zbywyKSwiJSIsIHNlcD0iIilgIHBvcHVsYXRpb24gZ3Jvd3RoLCBhbmQgYHIgcGFzdGUoMTAwICogcmVhbF9ncm93dGhfc28sIiUiLCBzZXA9IiIpYCBvZiByZWFsIGdyb3d0aCBwZXIgY2FwaXRhLiBUaGlzIGltcGxpZXMgdGhhdCB0YXggcmV2ZW51ZSBvdmVyIDEwIHllYXJzIDIwMTktMjAyOCBpcyBhYm91dCBgciByb3VuZCh0ZW5feWVhcl9mYWN0b3JfbW8sMSlgIHRpbWVzIHRoZSByZXZlbnVlIHJhaXNlZCBpbiAyMDE5W140XS4gVGhpcyB1bmlmb3JtIGdyb3d0aCBhc3N1bXB0aW9uIGlzIGNvbnNlcnZhdGl2ZSBhcyB0aGUgd2VhbHRoIG9mIHRoZSByaWNoIGhhcyBncm93biBzdWJzdGFudGlhbGx5IGZhc3RlciB0aGFuIGF2ZXJhZ2UgaW4gcmVjZW50IGRlY2FkZXMuIFRoZSBlc3RpbWF0ZXMgYnkgU2FleiBhbmQgWnVjbWFuW141XSBzaG93IHRoYXQsIGZyb20gMTk4MCB0byAyMDE2LCByZWFsIHdlYWx0aCBvZiB0aGUgdG9wIDAuMSUgaGFzIGdyb3duIGF0IDUuMyUgcGVyIHllYXIgb24gYXZlcmFnZSwgd2hpY2ggaXMgMi44IHBvaW50cyBhYm92ZSB0aGUgYXZlcmFnZSByZWFsIHdlYWx0aCBncm93dGggb2YgMi41JSBwZXIgeWVhci4gQXZlcmFnZSByZWFsIHdlYWx0aCBvZiB0aGUgRm9yYmVzIDQwMCBoYXMgZ3Jvd24gZXZlbiBmYXN0ZXIgYXQgNyUgcGVyIHllYXIsIDQuNSBwb2ludHMgYWJvdmUgdGhlIGF2ZXJhZ2UuIFRoZSBoaXN0b3JpY2FsIGdhcCBpbiBncm93dGggcmF0ZXMgb2YgdG9wIHdlYWx0aCB2cy4gYXZlcmFnZSB3ZWFsdGggaXMgbGFyZ2VyIHRoYW4gdGhlIHByb3Bvc2VkIHdlYWx0aCB0YXguIFRoZXJlZm9yZSwgZXZlbiB3aXRoIHRoZSB3ZWFsdGggdGF4LCBpdCBpcyBsaWtlbHkgdGhhdCB0b3Agd2VhbHRoIHdvdWxkIGNvbnRpbnVlIHRvIGdyb3cgYXQgbGVhc3QgYXMgZmFzdCBhcyB0aGUgYXZlcmFnZS4gIA0KDQpUaGlzIDEwLXllYXIgcHJvamVjdGlvbiBpbXBsaWVzIHRoYXQgcmV2ZW51ZSByYWlzZWQgYnkgdGhlIHByb2dyZXNzaXZlIHdlYWx0aCB0YXggd291bGQgYmUgYHIgcGFzdGUocm91bmQodGVuX3llYXJfZmFjdG9yX21vLDEpLCAiICogIiwgcm91bmQodG90YWxfdGF4X3JldiwxKSwgc2VwPSIiKWAgPSBgciBwYXN0ZSgiJCIsIHJvdW5kKHRlbl95ZWFyX3JldmVudWVfcGUpLCBzZXAgPSAiIilgIGJpbGxpb24sIHJvdW5kZWQgdG8gYHIgcGFzdGUoIiQiLCByb3VuZCh0ZW5feWVhcl9yZXZlbnVlX3BlLzFlMywgMSksIHNlcCA9ICIiKWAgdHJpbGxpb24uIE91dCBvZiB0aGlzIGByIHBhc3RlKCIkIiwgcm91bmQodGVuX3llYXJfcmV2ZW51ZV9wZS8xZTMsIDEpLCBzZXAgPSAiIilgIHRyaWxsaW9uLCB0aGUgYmlsbGlvbmFpcmUgc3VydGF4IHdvdWxkIHJhaXNlIGByIHBhc3RlMChyb3VuZCh0b3BfdGF4X3Jldl9pbiwxKSwgIiAqICIsIHJvdW5kKHRlbl95ZWFyX2ZhY3Rvcl9tbywxKSwgc2VwPSIiKWAgPSBgciBwYXN0ZTAoIiQiLCByb3VuZCh0ZW5feWVhcl90b3BfdGF4X3BlLDEpKWAgYmlsbGlvbiwgcm91bmRlZCB0byBgciBwYXN0ZSgiJCIsIHJvdW5kKHRlbl95ZWFyX3RvcF90YXhfcGUvMWUzLDEpLCBzZXAgPSIiKWAgdHJpbGxpb24uICANCg0KSXQgaXMgaW1wb3J0YW50IHRvIGVtcGhhc2l6ZSB0aGF0IG91ciBjb21wdXRhdGlvbnMgYXNzdW1lIHRoYXQgdGhlIHdlYWx0aCB0YXggYmFzZSBpcyBjb21wcmVoZW5zaXZlIHdpdGggbm8gbWFqb3IgYXNzZXQgY2xhc3NlcyBleGVtcHQgZnJvbSB3ZWFsdGggdGF4YXRpb24uIEludHJvZHVjaW5nIGV4ZW1wdGlvbnMgZm9yIHNwZWNpZmljIGFzc2V0IGNsYXNzZXMgd291bGQgcmVkdWNlIHRoZSByZXZlbnVlIGVzdGltYXRlcyBib3RoIG1lY2hhbmljYWxseSBhbmQgZHluYW1pY2FsbHkgYXMgd2VhbHRoeSBpbmRpdmlkdWFscyB3b3VsZCBzaGlmdCB0aGVpciB3ZWFsdGggaW50byB0YXggZXhlbXB0IGFzc2V0cy4gQmVjYXVzZSBTZW5hdG9yIFdhcnJlbidzIHByb3Bvc2FsIGRvZXMgbm90IGluY2x1ZGUgYW55IGxhcmdlIGV4ZW1wdGlvbnMsIHdlIGRvIG5vdCBiZWxpZXZlIG91ciByZXZlbnVlIGVzdGltYXRlIG5lZWRzIHRvIGJlIGFkanVzdGVkLg0KDQpgYGB7ciBvbmx5LWZ1bmN0aW9uLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyB0ZXN0IHRvIHJ1biBmcm9tIHRoZSBiZWdpbm5pbmcgKG9ubHkgZnVuY3Rpb25zKQ0Kcm0obGlzdCA9IGxzKClbIShscygpICVpbiUgbHMocGF0dGVybiA9ICJfZlxcYiIpKV0pDQppbnZpc2libGUoIGxpc3QyZW52KGNhbGxfc291cmNlc19mKCksIC5HbG9iYWxFbnYpICkNCmludmlzaWJsZSggbGlzdDJlbnYocG9saWN5X2YoKSwgLkdsb2JhbEVudikgKQ0KaW52aXNpYmxlKCBsaXN0MmVudih0YXhfZWxhc3RpY2l0eV9pbl9mKCksIC5HbG9iYWxFbnYpICkNCmludmlzaWJsZSggbGlzdDJlbnYodGF4X3JldmVudWVfbW9fZigpLCAuR2xvYmFsRW52KSApICNyZXBsYWNlDQppbnZpc2libGUoIGxpc3QyZW52KHRvdGFsX3Jldl9tb19mKCksIC5HbG9iYWxFbnYpICkgICNyZXBsYWNlDQppbnZpc2libGUoIGxpc3QyZW52KHRlbl95ZWFyc19tb19mKCksLkdsb2JhbEVudikgKQ0Kc2FwcGx5KGxzKHBhdHRlcm4gPSAiX3BlXFxiIiksIGdldCkNCmBgYA0KDQoNCg0KIyBWaXN1YWxpemF0aW9uIA0KDQpUaGUgZmlndXJlIGJlbG93IGlsbHVzdHJhdGVzIHRoZSBkaXN0cmlidXRpb24gb2Ygd2VhbHRoIHRheCBhY3Jvc3MgdGhlIHBvcHVsYXRpb246DQoNCmBgYHtyIGZpZ3VyZSwgd2FybmluZz1GQUxTRSwgZWNobz1wcmludF9jb2RlfSAgICAgICANCiMgQ2xlYW4gdXAgdGhlIGNvZGUgKGJ1dCBkbyBub3QgbWFrZSBjaGFuZ2VzKS4gICANCnRheFJhdGUgPC0gYyhtZWFuKHRheF9yYXRlc19wb1sxOjJdKSwgbWVhbih0YXhfcmF0ZXNfcG9bMzo1XSksIHRheF9yYXRlc19wb1s2XSwNCiAgICAgICAgICAgICB0YXhfcmF0ZXNfcG9bN10pICogMTAwDQpicmFja2V0cyA8LSBjKG1pbihicmFja2V0c19wb1sxOjJdKSwgbWluKGJyYWNrZXRzX3BvWzM6NV0pLCBicmFja2V0c19wb1s2XSwgDQogICAgICAgICAgICAgIGJyYWNrZXRzX3BvWzddKSAvIDFlNg0KI3RoaXMgc2VjdGlvbiBzb3J0cyB0aGUgdGF4IGJyYWNrZXRzLiBOb3QgbmVlZGVkIG91dHNpZGUgdGhlIGFwcCAgICANCmlmIChGQUxTRSl7ICAgICAgICAgIA0KICAgICMjIHJlc2h1ZmZsZSB0byBtYWtlIHN1cmUgYnJhY2tldHMgYXJlIGluY3JlYXNpbmcNCiAgICAjIyB0YXggcmF0ZXMgbm90IGZvcmNlZCB0byBiZSBtb25vdG9uaWMNCiAgICByZW9yZGVySWR4IDwtIG9yZGVyKGFzLm51bWVyaWMoYnJhY2tldHMpKQ0KICAgIGJyYWNrZXRzIDwtIGJyYWNrZXRzW3Jlb3JkZXJJZHhdDQogICAgdGF4UmF0ZSA8LSB0YXhSYXRlW3Jlb3JkZXJJZHhdDQp9DQogIA0KIyMjIEtBVElFOiBjaGFuZ2UgdGhlIDFlNSB0byB3aGF0ZXZlciB5b3Ugd2FudCB0byBiZSB0aGUgbWluaW11bQ0KeHZhbCA8LSAxMF5zZXEobG9nMTAoMWU1KSwgbG9nMTAobWF4KGdyaWQkdGhyZXNOZXcpKSwgYnkgPSAwLjAwMSkgIyMgZ2V0IHVuaWZvcm0gb24gbG9nIHNjYWxlDQogIyhtYXgoZ3JpZCR0aHJlc05ldykpDQppZihGQUxTRSl7DQogICAgaWR4MCA8LSB4dmFsIDw9IGFzLm51bWVyaWMoYnJhY2tldHNbMV0pICogMWU2DQogICAgaWR4MSA8LSB4dmFsIDw9IGFzLm51bWVyaWMoYnJhY2tldHNbMl0pICogMWU2ICYgeHZhbCA+IGFzLm51bWVyaWMoYnJhY2tldHNbMV0pICogMWU2DQogICAgaWR4MiA8LSB4dmFsID4gYXMubnVtZXJpYyhicmFja2V0c1syXSkgKiAxZTYgJiB4dmFsIDw9IGFzLm51bWVyaWMoYnJhY2tldHNbM10pICogMWU2DQogICAgaWR4MyA8LSB4dmFsID4gYXMubnVtZXJpYyhicmFja2V0c1szXSkgKiAxZTYgJiB4dmFsIDw9IGFzLm51bWVyaWMoYnJhY2tldHNbNF0pICogMWU2DQogICAgaWR4NCA8LSB4dmFsID4gYXMubnVtZXJpYyhicmFja2V0c1s0XSkgKiAxZTYNCiAgICBpZHggPC0gY2JpbmQuZGF0YS5mcmFtZShpZHgwLCBpZHgxLCBpZHgyLCBpZHgzLCBpZHg0KQ0KICAgIyBJbmRpY2F0b3IgYWNyb3NzIGluY29tZSBvbiB0YXggYnJhY2tldCBwb3NpdGlvbg0KICAgIGdldEdyb3VwIDwtIHVubGlzdChhcHBseShpZHgsIDEsIGZ1bmN0aW9uKHgpIHsNCiAgICAgIHdoaWNoKHgpWzFdDQogICAgfSkpDQoNCiAgICB0b1Bsb3QgPC0gY2JpbmQuZGF0YS5mcmFtZSh4dmFsLCBnZXRHcm91cCkgIA0KfQ0KICAgICNicmFja2V0c19wbyA8LSBjKDAsIDI1LCA1MCwgMTAwLCAyNTAsIDUwMCwgMTAwMCkgKiAxZTYNCmdldEdyb3VwIDwtIGFzLm51bWVyaWMoY3V0KHh2YWwsIGMoMCwgYnJhY2tldHMgKiAxZTYsIDFlMTIpLCBpbmNsdWRlLmxvd2VzdCA9IFRSVUUpKQ0KDQp0b1Bsb3QgPC0gY2JpbmQuZGF0YS5mcmFtZSh4dmFsLCBnZXRHcm91cCkgIA0KI3N1bW1hcnkodG9QbG90KQ0KI3RvTWF0Y2ggPC0gY2JpbmQuZGF0YS5mcmFtZShncm91cCA9IDE6NywgdGF4ID0gdGF4X3JhdGVzX3BvKQ0KdG9NYXRjaCA8LSBjYmluZC5kYXRhLmZyYW1lKGdyb3VwID0gMToobGVuZ3RoKHRheFJhdGUpICsgMSksIHRheCA9IGMoMCwgdGF4UmF0ZSkpDQogDQp0b1Bsb3QyIDwtIG1lcmdlKHRvUGxvdCwgdG9NYXRjaCwgYnkueCA9ICJnZXRHcm91cCIsIGJ5LnkgPSAiZ3JvdXAiKQ0KDQojbGFwcGx5KHggPSAxOjUsIGYoeCx5KSwgeSA9IDY6MTApID0gKDEsIDY6MTApOyAoMiwgNjoxMCk7Li4uIDsoNSwgNjoxMCkgIA0KdG9QbG90MiRhdmVyYWdlSW50IDwtIHNhcHBseSggdG9QbG90MiR4dmFsLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIGdldF90YXhfcmV2KHdlYWx0aF92YXIgPSB4LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGF4cmF0ZXNfdmFyID0gdGF4UmF0ZS8xMDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFja2V0c192YXIgPSBicmFja2V0cyAqIDFlNikgKQ0KDQojIEhlcmUgaXMgd2hlcmUgdGhlIHRvdGFsIHRheCBwYXllZCBieSBlYWNoIGluZGl2aWR1YWxzIGlzIHRyYW5zZm9ybSBpbnRvIGF2ZXJhZ2UgdGF4IHJhdGVzDQp0b1Bsb3QyJGF2ZXJhZ2VSYXRlIDwtICh0b1Bsb3QyJGF2ZXJhZ2VJbnQgLyB0b1Bsb3QyJHh2YWwpICogMTAwDQoNCnRvUGxvdDIkaWQgPC0gMTpucm93KHRvUGxvdDIpDQojYnJvd3NlcigpDQppZihGQUxTRSkgew0KICAgICMgdW5hZmZlY3RlZCBieSBuZXcgZ3JvdXBpbmcNCiAgICB0b1Bsb3QyJG1hcmdpbmFsSW50IDwtIHVubGlzdChsYXBwbHkodG9QbG90MiR4dmFsLCBnZXRBdmVyYWdlVGF4LCB0YXhSYXRlLCBicmFja2V0cykpDQoNCiAgICB0b1Bsb3QyJG1hcmdpbmFsUmF0ZSA8LSAodG9QbG90MiRtYXJnaW5hbEludCAvIHRvUGxvdDIkeHZhbCkgKiAxMDANCg0KDQogICAgdG9QbG90MiRpZCA8LSAxOm5yb3codG9QbG90MikNCn0NCiNzdW1tYXJ5KHRvUGxvdDIpDQojZW5kIG9mIGRhdGFJbnB1dFQNCiAgIA0KIyBUaGVzZSBhcmUgbWluaSBkYXRhIHNldCB0aGF0IGdndmlzIG5lZWRzIHRvIGNyZSBhdGUgdmVydGljYWwgbGluZXMNCmV4dHJhMCA8LSBjYmluZC5kYXRhLmZyYW1lKHggPSByZXAobWF4KGFzLm51bWVyaWMoYnJhY2tldHNbMV0pICogMWU2LCAxZTUpLCAyKSwgeSA9IGMoMCwgdGF4UmF0ZVsxXSkpDQpleHRyYTEgPC0gY2JpbmQuZGF0YS5mcmFtZSh4ID0gcmVwKGFzLm51bWVyaWMoYnJhY2tldHNbMl0pICogMWU2LCAyKSwgeSA9IGMoMCwgdGF4UmF0ZVsxXSkpDQpleHRyYTFiIDwtIGNiaW5kLmRhdGEuZnJhbWUoeCA9IHJlcChhcy5udW1lcmljKGJyYWNrZXRzWzJdKSAqIDFlNiwgMiksIHkgPSBjKDAsIHRheFJhdGVbMl0pKQ0KZXh0cmEyIDwtIGNiaW5kLmRhdGEuZnJhbWUoeCA9IHJlcChhcy5udW1lcmljKGJyYWNrZXRzWzNdKSAqIDFlNiwgMiksIHkgPSBjKDAsIHRheFJhdGVbMl0pKQ0KZXh0cmEyYiA8LSBjYmluZC5kYXRhLmZyYW1lKHggPSByZXAoYXMubnVtZXJpYyhicmFja2V0c1szXSkgKiAxZTYsIDIpLCB5ID0gYygwLCB0YXhSYXRlWzNdKSkNCmV4dHJhMyA8LSBjYmluZC5kYXRhLmZyYW1lKHggPSByZXAoYXMubnVtZXJpYyhicmFja2V0c1s0XSkgKiAxZTYsIDIpLCB5ID0gYygwLCB0YXhSYXRlWzNdKSkNCmV4dHJhM2IgPC0gY2JpbmQuZGF0YS5mcmFtZSh4ID0gcmVwKGFzLm51bWVyaWMoYnJhY2tldHNbNF0pICogMWU2LCAyKSwgeSA9IGMoMCwgdGF4UmF0ZVs0XSkpDQoNCnNob3dBdmcgPC0gZnVuY3Rpb24oeCkgew0KICAjIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI4Mzk2OTAwL3ItZ2d2aXMtaHRtbC1mdW5jdGlvbi1mYWlsaW5nLXRvLWFkZC10b29sdGlwLzI4Mzk5NjU2IzI4Mzk5NjU2DQogICMgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzEyMzAxMjQvZXhjbHVkZS1saW5lLXBvaW50cy1mcm9tLXNob3dpbmctaW5mby13aGVuLXVzaW5nLWFkZC10b29sdGlwLXdpdGgtaG92ZXItaW4tZ2d2aXMNCiAgaWYgKHN1bShncmVwbCgiaWQiLCBuYW1lcyh4KSkpID09IDApIHJldHVybihOVUxMKQ0KICBpZiAoaXMubnVsbCh4KSkgcmV0dXJuKE5VTEwpDQogIA0KICBkYXRhIDwtIHRvUGxvdDINCg0KICByb3cgPC0gZGF0YVtkYXRhJGlkID09IHgkaWQsIF0NCg0KICAjVGhlIGZvbGxvd2luZyBzZWN0aW9uIGRvZXMgbm90IHdvcmsgaW4gdGhlIHN0YXRpYyBwbG90DQogIGlmKEZBTFNFKXsNCiAgcGFzdGUwKCJBdmVyYWdlIFRheCBSYXRlOiAiLCByb3VuZChyb3ckYXZlcmFnZVJhdGUsIDIpLCAiJSIsIA0KICAgICAgICAgIiA8YnI+IFdlYWx0aCAoJG0pOiAiLCByb3VuZChyb3ckeHZhbCAvIDFlNiwgMCksIA0KICAgICAgICAgIjxicj4gVG9wICIsIGdldFBlcmNlbnRpbGUoZ3JpZCwgcm93JHh2YWwgLyAxZTYpLCANCiAgICAgICAgICIlIiwgIjxicj4gVGF4ZXMgUGFpZCAoJG0pOiAiLCByb3VuZChyb3ckYXZlcmFnZUludCAvIDFlNiwgMiksIA0KICAgICAgICAgc2VwID0gIiIpICMjIGRpdmlkaW5nIGJ5IDFlNiBtYXkgbmVlZCB0byBjaGFuZ2UgaWYgd2UgZG8gdGhpcyBmb3IgeHZhbCBvdmVyYWxsDQogIH0NCn0NCg0KDQpnZXRQZXJjZW50aWxlTWFya2VycyA8LSBmdW5jdGlvbihncmlkKSB7DQogICAgYygNCiAgICAgIGdyaWQkdGhyZXNOZXdbd2hpY2goZ3JpZCRncGVyYyA9PSA5MCldLA0KICAgICAgZ3JpZCR0aHJlc05ld1t3aGljaChncmlkJGdwZXJjID09IDk5KV0sDQogICAgICBncmlkJHRocmVzTmV3W3doaWNoKGdyaWQkZ3BlcmMgPj0gOTkuOSAmIGdyaWQkZ3BlcmMgPCA5OS45OSlbMV1dLA0KICAgICAgZ3JpZCR0aHJlc05ld1t3aGljaChncmlkJGdwZXJjID49IDk5Ljk5ICYgZ3JpZCRncGVyYyA8IDk5Ljk5OSlbMV1dDQogICAgKQ0KICB9DQoNCmRhdGEgPC0gdG9QbG90Mg0KDQptYXJrZXJzIDwtIGRhdGEuZnJhbWUoYSA9IGMoZ2V0UGVyY2VudGlsZU1hcmtlcnMoZ3JpZCkgLyAxZTYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGdyaWQkdGhyZXNOZXcpIC8gMWU2KSwgDQogICAgICAgICAgICAgICAgICAgICBiID0gcmVwKDAuMjUsIDUpLCANCiAgICAgICAgICAgICAgICAgICAgIGMgPSBjKCJUb3AgMTAlIiwgIlRvcCAxJSIsICJUb3AgMC4xJSIsICJUb3AgMC4wMSUiLCAiTWF4aW11bSIpKQ0KDQp2YWx1ZXNJbnQgPC0gYyhicmFja2V0cywgcm91bmQobWF4KGdyaWQkdGhyZXNOZXcpIC8gMWU2LCAyKSwgDQogICAgICAgICAgICAgICByb3VuZChnZXRQZXJjZW50aWxlTWFya2VycyhncmlkKSAvIDFlNiwgMikpDQp2YWx1ZXNJbnQgPC0gc29ydCh2YWx1ZXNJbnQpDQpybUlkeCA8LSBuY29sKGRhdGEpDQpwbG90IDwtIGRhdGFbLCAtcm1JZHhdICU+JQ0KICBnZ3Zpcyh4ID0gfiB4dmFsIC8gMWU2LCB5ID0gfnRheCkgJT4lDQogIGxheWVyX3BvaW50cygpICU+JQ0KICBsYXllcl9wb2ludHMoZGF0YSA9IHN1YnNldChkYXRhLCB4dmFsIC8gMWU2IDw9IG1heChncmlkJHRocmVzTmV3KSAvIDFlNiksIA0KICAgICAgICAgICAgICAgeCA9IH4geHZhbCAvIDFlNiwgDQogICAgICAgICAgICAgICB5ID0gfmF2ZXJhZ2VSYXRlLCBzdHJva2UgOj0gInJlZCIsIGtleSA6PSB+aWQpICU+JQ0KICBhZGRfdG9vbHRpcChzaG93QXZnLCAiaG92ZXIiKSAlPiUNCiAgIyBsYXllcl9saW5lcyhkYXRhID0gc3Vic2V0KGRhdGEseHZhbC8xZTY8PTQ1MDAwKSx4ID0gfiB4dmFsIC8gMWU2LCB5ID0gfm1hcmdpbmFsUmF0ZSwgc3Ryb2tlIDo9ICJyZWQiKSAlPiUNCiAgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMSwgfiB4IC8gMWU2LCB+eSkgJT4lDQogICMgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMiwgfiB4IC8gMWU2LCB+eSkgJT4lDQogICMgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMywgfiB4IC8gMWU2LCB+eSkgJT4lDQogIGxheWVyX3BhdGhzKGRhdGEgPSBleHRyYTAsIH4geCAvIDFlNiwgfnkpICU+JQ0KICBsYXllcl9wYXRocyhkYXRhID0gZXh0cmExYiwgfiB4IC8gMWU2LCB+eSkgJT4lDQogICMgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMmIsIH4geCAvIDFlNiwgfnkpICU+JQ0KICAjIGxheWVyX3BhdGhzKGRhdGEgPSBleHRyYTNiLCB+IHggLyAxZTYsIH55KSAlPiUNCiAgbGF5ZXJfdGV4dChkYXRhID0gbWFya2VycywgfmEsIH5iLCB0ZXh0IDo9IH5jLCBhbGlnbiA6PSAiY2VudGVyIiwgZm9udFdlaWdodCA6PSAiYm9sZCIpICU+JQ0KICBhZGRfYXhpcygieCIsDQogICAgdGl0bGVfb2Zmc2V0ID0gODAsIHRpdGxlID0gIldlYWx0aCAoJG0pIiwgZ3JpZCA9IEYsIGZvcm1hdCA9ICIsIiwNCiAgICB2YWx1ZXMgPSB2YWx1ZXNJbnQsIHByb3BlcnRpZXMgPSANCiAgICAgIGF4aXNfcHJvcHMobGFiZWxzID0gbGlzdChhbmdsZSA9IDQ1LCBhbGlnbiA9ICJsZWZ0IiwgYmFzZWxpbmUgPSAibWlkZGxlIikpDQogICkgJT4lDQogIGFkZF9heGlzKCJ5IiwgdGl0bGUgPSAiVGF4IHJhdGUgKCUpIikgJT4lDQogIHNjYWxlX251bWVyaWMoIngiLCB0cmFucyA9ICJsb2ciLCBleHBhbmQgPSAwKSAlPiUNCiAgc2V0X29wdGlvbnMod2lkdGggPSA4MDAsIGhlaWdodCA9IDUwMCkgJT4lDQogICAgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMiwgfiB4IC8gMWU2LCB+eSkgJT4lDQogICAgbGF5ZXJfcGF0aHMoZGF0YSA9IGV4dHJhMmIsIH4geCAvIDFlNiwgfnkpICU+JQ0KICAgIGxheWVyX3BhdGhzKGRhdGEgPSBleHRyYTMsIH4geCAvIDFlNiwgfnkpICU+JQ0KICAgIGxheWVyX3BhdGhzKGRhdGEgPSBleHRyYTNiLCB+IHggLyAxZTYsIH55KQ0KICBwbG90DQogIA0KYGBgDQogPGZvbnQgc2l6ZT0iNCI+IFRheCByZXZlbnVlIGZyb20gd2VhbHRoIHRheCBpbiBmaXJzdCB5ZWFyOiBgciBwYXN0ZTAoIiQiLCByb3VuZCh0b3RhbF90YXhfcmV2KSlgIGJpbGxpb24gPC9mb250PiAgDQogDQogPGZvbnQgc2l6ZT0iNCI+IFRheCByZXZlbnVlIGZyb20gd2VhbHRoIHRheCBvdmVyIDEwIHllYXI6IGByIHBhc3RlMCgiJCIsIHJvdW5kKHRlbl95ZWFyX3JldmVudWVfcGUvMWUzLCAxKSlgIHRyaWxsaW9uPC9mb250Pg0KDQogPGZvbnQgc2l6ZT0iNCI+IFBlcmNlbnRhZ2Ugb2YgVVMgaG91c2Vob2xkcyBwYXlpbmcgdGhlIHdlYWx0aCB0YXg6IGByIHBhc3RlMChyb3VuZCh0YXJnZXRfaGhsZHNfbW8vdG90YWxfaGhsZHNfc28gKiAxMDAgLCBkaWdpdHMgPSAyKSwgIiUiKWA8L2ZvbnQ+DQoNCg0KKipbQ2xpY2sgaGVyZV0oaHR0cDovL3dlYWx0aHRheHNpbXVsYXRvci5vcmcvc2ltdWxhdG9yX2FwcC8pIHRvIGV4cGxvcmUgZGlmZmVyZW50IHBvbGljeSBwcm9wb3NhbHMgYW5kIHRvIHNlZSBob3cgdGhlIGFzc3VtcHRpb25zIG9mIHRoZSBhbmFseXNpcyBhZmZlY3QgdGhlIHJlc3VsdHMuKioNCg0KKipUaGVyZSBhcmUgdHdvIHdheXMgdG8gZWRpdCB0aGUgY29kZSBiZWhpbmQgdGhpcyBkb2N1bWVudDoqKiAgIA0KMSAtIERvd25sb2FkL0Nsb25lIFt0aGlzIHJlcG9zaXRvcnldKGh0dHBzOi8vZ2l0aHViLmNvbS9maG9jZXMvb3BhLXdlYWx0aHRheCkgaW50byB5b3VyIGNvbXB1dGVyLiBZb3Ugd2lsbCBuZWVkIHRvIGluc3RhbGwgW1JdKGh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZy8pIGFuZCBbUlN0dWRpb10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC8jZG93bmxvYWQpLiAgICANCg0KMiAtIEdvIHRvIFt0aGlzIGxpbmtdKGh0dHBzOi8vbXliaW5kZXIub3JnL3YyL2doL2Zob2Nlcy9vcGEtd2VhbHRodGF4L21hc3Rlcj91cmxwYXRoPXJzdHVkaW8pIGFuZCByZXByb2R1Y2UgYWxsIHRoZSByZXN1bHRzIGluIGEgY29tcHV0aW5nIGVudmlyb21lbnQgKHN1cHBvcnRlZCBieSBbcHJvamVjdCBiaW5kZXJdKGh0dHBzOi8vbXliaW5kZXIub3JnLykpLiBZb3Ugd2lsbCAqKm5vdCoqIG5lZWQgdG8gaW5zdGFsbCBhbnl0aGluZyBpbiB5b3VyIGNvbXB1dGVyLiAgDQoNCg0KIyBXZWFsdGggaW5lcXVhbGl0eSANCk9uZSBvZiB0aGUga2V5IG1vdGl2YXRpb25zIGZvciBpbnRyb2R1Y2luZyBhIHByb2dyZXNzaXZlIHdlYWx0aCB0YXggaXMgdG8gY3VyYiB0aGUNCmdyb3dpbmcgY29uY2VudHJhdGlvbiBvZiB3ZWFsdGguIFRoZSB0b3AgMC4xJSB3ZWFsdGggc2hhcmUgaGFzIGluY3JlYXNlZCBkcmFtYXRpY2FsbHkgZnJvbSBhYm91dCA3JSBpbiB0aGUgbGF0ZSAxOTcwcyB0byBhcm91bmQgMjAlIGluIHJlY2VudCB5ZWFycy4gQ29udmVyc2VseSwgdGhlIHdlYWx0aCBzaGFyZSBvZiB0aGUgYm90dG9tIDkwJSBvZiBmYW1pbGllcyBoYXMgZGVjbGluZWQgZnJvbSBhYm91dCAzNSUgaW4gdGhlIGxhdGUgMTk3MHMgdG8gYWJvdXQgMjUlIHRvZGF5LiBUaGlzIGZhbGwgaGFzIGJlZW4gcHJpbWFyaWx5IHRoZSBjb25zZXF1ZW5jZSBvZiBpbmNyZWFzZWQgZGVidCBmb3IgdGhlIGJvdHRvbSA5MCUgKHRocm91Z2ggbW9ydGdhZ2UgcmVmaW5hbmNlLCBjb25zdW1lciBjcmVkaXQsIGFuZCBzdHVkZW50IGxvYW5zKS4gQXMgYSByZXN1bHQsIHRoZSB0b3AgMC4xJSB0b2RheSBvd25zIGFsbW9zdCBhcyBtdWNoIHdlYWx0aCBhcyB0aGUgYm90dG9tIDkwJSBvZiBVUyBmYW1pbGllcy4gDQoNCg0KIyBUYXggYnVyZGVuIG9uIHRoZSB3ZWFsdGhpZXN0IDAuMSUgDQoNClRoZSBlc3RpbWF0ZXMgb2YgUGlrZXR0eSwgU2FleiwgYW5kIFp1Y21hbiAoMjAxOCkgc2hvdyB0aGF0IHRoZSB0b3RhbCBidXJkZW4gKGluY2x1ZGluZyBhbGwgdGF4ZXMgYXQgdGhlIGZlZGVyYWwsIHN0YXRlLCBhbmQgbG9jYWwgbGV2ZWxzKSBvZiB0aGUgd2VhbHRoaWVzdCAwLjElIGZhbWlsaWVzIGlzIHByb2plY3RlZCB0byBiZSAzLjIlIG9mIHRoZWlyIHdlYWx0aCBpbiAyMDE5ICh0aGV5IGhhdmUgb24gYXZlcmFnZSBcJDExNiBtaWxsaW9uIGluIHdlYWx0aCwgYW5kIHBheSB0b3RhbCBvZiBcJDMuNjggbWlsbGlvbiBpbiB0YXhlcykuIFRoZSBwcm9wb3NlZCBwcm9ncmVzc2l2ZSB3ZWFsdGggdGF4IHdvdWxkIGFkZCBhbiBleHRyYSBcJDEuMjcgbWlsbGlvbiAob3IgMS4xJSBvZiB3ZWFsdGgpIHRvIHRoZWlyIHRheCBidXJkZW4gZm9yIGEgdG90YWwgdGF4IGJ1cmRlbiAocmVsYXRpdmUgdG8gd2VhbHRoKSBvZiA0LjMlLg0KDQpJbiBjb250cmFzdCwgdGhlIGJvdHRvbSA5OSUgZmFtaWxpZXMgaGF2ZSBhIHRvdGFsIHRheCBidXJkZW4gb2YgNy4yJSByZWxhdGl2ZSB0byB0aGVpciB3ZWFsdGguIFRoZWlyIHRheCBidXJkZW4gcmVsYXRpdmUgdG8gd2VhbHRoIGlzIG11Y2ggaGlnaGVyIHRoYW4gZm9yIHRoZSB0b3AgMC4xJSBiZWNhdXNlIHRoZSBib3R0b20gOTklIHJlbGllcyBwcmltYXJpbHkgb24gbGFib3IgaW5jb21lLCB3aGljaCBiZWFycyB0YXggYnV0IGlzIG5vdCBwYXJ0IG9mIG5ldCB3b3J0aC4gSW4gY29udHJhc3QsIHRoZSBtYWpvcml0eSBvZiB0aGUgaW5jb21lIG9mIHRoZSB0b3AgMC4xJSB3ZWFsdGhpZXN0IGNvbWVzIGZyb20gcmV0dXJucyB0byB0aGVpciB3ZWFsdGguDQoNCg0KKipOb3RlOioqIE91ciBhbmFseXNpcyBjb21wbGllcyB3aXRoIHRoZSBoaWdoZXN0IGxldmVscyBvZiB0cmFuc3BhcmVuY3kgYW5kIHJlcHJvZHVjaWJpbHR5IGZvciBvcGVuIHBvbGljeSBhbmFseXNpcyBwcm9wb3NlZCBieSB0aGUgW19CZXJrZWxleSBJbml0aWF0aXZlIGZvciBUcmFuc3BhcmVuY3kgaW4gdGhlIFNvY2lhbCBTY2llbmNlc19dKGh0dHBzOi8vd3d3LmJpdHNzLm9yZy9vcGEvKS4gV2UgaW52aXRlIGNvbnRyaWJ1dG9ycyBhbmQgY3JpdGljcyBvZiB0aGlzIGFuYWx5c2lzIHRvIGZvbGxvdyBzaW1pbGFyIHN0YW5kYXJkcy4gDQoNCiMgUmVmZXJlbmNlcyB7LX0NCg0KW14xXTogVGhlIGF1dGhvcnMgd291bGQgbGlrZSB0byBwYXJ0aWN1bGFybHkgYWNrbm93bGVkZ2UgdGhlIGV4Y2VsbGVudCByZXNlYXJjaCBhc3NpdGFuc2hpcCBvZiBLYXRpZSBEb25uZWxseSBNb3JhbiBhbmQgQ2xhbmN5IEdyZWVuLiANCg0KW14yXTogVGhpcyBkeW5hbWljIGRvY3VtZW50IGlzIHBhcnQgb2YgYW4gT3BlbiBQb2xpY3kgQW5hbHlzaXMgd2hpY2ggZm9sbG93cyB0aGUgZ3VpZGVsaW5lcyBvZiB0aGUgW0JlcmtlbGV5IEluaXRpYXRpdmUgZm9yIFRyYW5zcGFyZW5jeSBpbiB0aGUgU29jaWFsIFNjaWVuY2VzXShodHRwczovL3d3dy5iaXRzcy5vcmcvb3BhLykNCg0KW140XTogV2l0aCByPWByIHBhc3RlMCgxMDAgKiBkaXNjb3VudF9yYXRlX21vLCAiJSIpYCwgd2UgaGF2ZSBbMSsoMStyKSsuLisoMStyKV45XT1bKDErcileMTAtMV0vcj1gciByb3VuZChzdW0oKDEgKyBkaXNjb3VudF9yYXRlX21vKV4oMDo5KSksMSlgLCBvciBhcHByb3hpbWF0ZWx5IDEzLg0KDQpbXjVdOiBTYWV6LCBFbW1hbnVlbCBhbmQgR2FicmllbCBadWNtYW4sICJXZWFsdGggSW5lcXVhbGl0eSBpbiB0aGUgVW5pdGVkIFN0YXRlcyBzaW5jZSAxOTEzOiBFdmlkZW5jZSBmcm9tIENhcGl0YWxpemVkIEluY29tZSBUYXggRGF0YSIsIFF1YXJ0ZXJseSBKb3VybmFsIG9mIEVjb25vbWljcyAxMzEoMiksIDIwMTYsIDUxOS01NzgsIHVwZGF0ZWQgc2VyaWVzIGF2YWlsYWJsZSBhdCBodHRwOi8vZ2FicmllbC16dWNtYW4uZXUvdXNkaW5hLw==

An Open Policy Analysis by BITSS
See a full contributors list here
opa@berkeley.edu